spi: add runtime support

This commit is contained in:
Robert Jördens 2016-02-29 00:38:36 +01:00
parent 8d7e92ebae
commit d63a63531a
4 changed files with 75 additions and 1 deletions

View File

@ -7,7 +7,7 @@ OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
session.o log.o analyzer.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
bridge.o rtio.o ttl.o dds.o
bridge.o rtio.o ttl.o dds.o spi.o
CFLAGS += -I$(LIBALLOC_DIRECTORY) \
-I$(MISOC_DIRECTORY)/software/include/dyld \

View File

@ -15,6 +15,7 @@
#include "artiq_personality.h"
#include "ttl.h"
#include "dds.h"
#include "spi.h"
#include "rtio.h"
double round(double x);
@ -121,6 +122,9 @@ static const struct symbol runtime_exports[] = {
{"dds_batch_exit", &dds_batch_exit},
{"dds_set", &dds_set},
{"spi_write", &spi_write},
{"spi_read", &spi_read},
{"cache_get", &cache_get},
{"cache_put", &cache_put},

50
artiq/runtime/spi.c Normal file
View File

@ -0,0 +1,50 @@
#include <generated/csr.h>
#include <stdio.h>
#include "artiq_personality.h"
#include "rtio.h"
#include "log.h"
#include "spi.h"
#define DURATION_WRITE (1 << CONFIG_RTIO_FINE_TS_WIDTH)
void spi_write(long long int timestamp, int channel, int addr,
unsigned int data)
{
rtio_chan_sel_write(CONFIG_RTIO_SPI_CHANNEL + channel);
rtio_o_address_write(addr);
rtio_o_data_write(data);
rtio_o_timestamp_write(timestamp);
rtio_write_and_process_status(timestamp, channel);
}
unsigned int spi_read(long long int timestamp, int channel, int addr)
{
int status;
long long int time_limit = timestamp + DURATION_WRITE;
unsigned int r;
spi_write(timestamp, channel, addr | SPI_WB_READ, 0);
while((status = rtio_i_status_read())) {
if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) {
rtio_i_overflow_reset_write(1);
artiq_raise_from_c("RTIOOverflow",
"RTIO overflow at channel {0}",
channel, 0, 0);
}
if(rtio_get_counter() >= time_limit) {
/* check empty flag again to prevent race condition.
* now we are sure that the time limit has been exceeded.
*/
if(rtio_i_status_read() & RTIO_I_STATUS_EMPTY)
return -1;
}
/* input FIFO is empty - keep waiting */
}
r = rtio_i_data_read();
rtio_i_re_write(1);
return r;
}

20
artiq/runtime/spi.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __SPI_H
#define __SPI_H
#include <hw/common.h>
#include <generated/csr.h>
#include <generated/mem.h>
#define SPI_ADDR_DATA 0
#define SPI_ADDR_XFER 1
#define SPI_ADDR_CONFIG 2
#define SPI_WB_READ (1 << 2)
#define SPI_XFER_CS(x) (x)
#define SPI_XFER_WRITE_LENGTH(x) ((x) << 16)
#define SPI_XFER_READ_LENGTH(x) ((x) << 24)
void spi_write(long long int timestamp, int channel, int address, unsigned int data);
unsigned int spi_read(long long int timestamp, int channel, int address);
#endif /* __SPI_H */