Add USB/UART interface - #1
Conversation
cozzyd
left a comment
There was a problem hiding this comment.
this looks pretty good, the main thing I would do is make uart_device optional and then complain if you try to use it but it's not there.
| didaq_dev_t * didaq_open(const didaq_setup_t * setup) | ||
| { | ||
| if (!setup || !setup->spi_device || !*setup->spi_device) return NULL; | ||
| if (!setup || !setup->spi_device || !*setup->spi_device || !setup->uart_device || !*setup->uart_device) return NULL; |
There was a problem hiding this comment.
I wouldn't make the uart_device mandatory. Just complain if you try to do something that requires it? (you can always check if it's been passed by looking at dev->setup.uart_device)
| ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bpw); | ||
|
|
||
|
|
||
| int uart_fd = open(setup->uart_device, O_RDWR); |
There was a problem hiding this comment.
again i would make it optional here (but if it's passed, failure to open should indeed be fatal)
|
|
||
| int didaq_uart_read(didaq_dev_t * dev, uint32_t addr, uint8_t num_words) | ||
| { | ||
| usleep(10000); |
There was a problem hiding this comment.
why a sleep at the beginning here?
There was a problem hiding this comment.
My error might've been not properly reading from the uart_fd for all data to arrive, or if packets were piling up in firmware and causing race issues. I will double check if it still fails without sleeps when waiting for all data.
There was a problem hiding this comment.
right, but this is before you send something to it? the sleep should be somewhere else if needed.
| memset(dev->uart_rx_buf, 0, sizeof(dev->uart_rx_buf)); | ||
| usleep(50000); | ||
|
|
||
| int ret_bytes = read(dev->uart_fd, dev->uart_rx_buf, num_words*BYTES_PER_WORD); |
There was a problem hiding this comment.
you set the serial port to non-blocking, didn't you? you should probably keep reading with a timeout until you get 6 bytes...
There was a problem hiding this comment.
(i.e. read wil lreturn with 0 immediately if nthing is available... so keep reading in a loop until you get to 6 bytes or more time than you'd like has elapsed)
|
|
||
| int didaq_uart_write(didaq_dev_t * dev, uint32_t addr, uint32_t data, uint8_t num_words) | ||
| { | ||
| usleep(10000); // tune val... basically the fpga is much slower than the sbc |
There was a problem hiding this comment.
again doesn't really make sense to sleep at the start here...
| // Setup readout | ||
| didaq_reset_acq(dev); | ||
|
|
||
| static uint8_t wfs[DIDAQ_NUM_CHANNELS][1024]; |
There was a problem hiding this comment.
not that important now, but this doesnt' support multiple didaq instances. the better way to do this is to reserve space inside the didaq_dev for this.
|
|
||
| didaq_event_readout_t rdout = { .in = {.len = 1024, .start = 0}, .wfs = | ||
| { | ||
| wfs[0], wfs[1], wfs[2], wfs[3], wfs[4], wfs[5], |
There was a problem hiding this comment.
we should maybe write a macro to make this assignment less painful
…cks to functions/methods that need uart
Adds in USB/UART support for access to the Avalon registers (ie the ADC SPI controller).
Can be used to access user registers, but is currently only focused to ADC registers, since the interface will be much slower and has to awkwardly buffer in packets to the Avalon-SPI controller. The interface is added to the DiDAQ struct, and only methods needing to access the ADCs should use it (unless we can speed up the IO and move scalers/thresholds away from SPI).
UART interface setup and checking pulled from librno-g/src/radiant.c, and interface is ported from pydidaq