X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=drv%2Fser.c;h=0838bc1538855e6c58575d0c6107d16b2981c485;hb=2535cb94ec2183791128f8bbd109ca69a960cf78;hp=7daac36096c51dcf7c1000fa377f24ad2072ffe8;hpb=dd4c57ad1010a2347247fd6bbcce30956d3de791;p=bertos.git diff --git a/drv/ser.c b/drv/ser.c index 7daac360..0838bc15 100644 --- a/drv/ser.c +++ b/drv/ser.c @@ -85,33 +85,29 @@ #endif -/* Serial configuration parameters */ -#define SER_CTSDELAY 70 /**< CTS line retry interval (ms) */ -#define SER_TXPOLLDELAY 2 /**< Transmit buffer full retry interval (ms) */ -#define SER_RXPOLLDELAY 2 /**< Receive buffer empty retry interval (ms) */ - - struct Serial ser_handles[SER_CNT]; - /** - * Inserisce il carattere c nel buffer di trasmissione. - * Questa funzione mette il processo chiamante in attesa - * quando il buffer e' pieno. + * Insert \a c in tx FIFO buffer. + * \note This function will switch out the calling process + * if the tx buffer is full. If the buffer is full + * and \a port->txtimeout is 0 return EOF immediatly. * - * \return EOF in caso di errore o timeout, altrimenti - * il carattere inviato. + * \return EOF on error or timeout, \a c otherwise. */ static int ser_putchar(int c, struct Serial *port) { - //ASSERT_VALID_FIFO(&port->txfifo); if (fifo_isfull_locked(&port->txfifo)) { #if CONFIG_SER_TXTIMEOUT != -1 + /* If timeout == 0 we don't want to wait */ + if (port->txtimeout == 0) + return EOF; + ticks_t start_time = timer_clock(); #endif - /* Attende finche' il buffer e' pieno... */ + /* Wait while buffer is full... */ do { wdt_reset(); @@ -141,19 +137,22 @@ static int ser_putchar(int c, struct Serial *port) /** - * Preleva un carattere dal buffer di ricezione. - * Questa funzione mette il processo chiamante in attesa - * quando il buffer e' vuoto. L'attesa ha un timeout - * di ser_rxtimeout millisecondi. + * Fetch a character from the rx FIFO buffer. + * \note This function will switch out the calling process + * if the rx buffer is empty. If the buffer is empty + * and \a port->rxtimeout is 0 return EOF immediatly. * - * \return EOF in caso di errore o timeout, altrimenti - * il carattere ricevuto. + * \return EOF on error or timeout, \a c otherwise. */ static int ser_getchar(struct Serial *port) { if (fifo_isempty_locked(&port->rxfifo)) { #if CONFIG_SER_RXTIMEOUT != -1 + /* If timeout == 0 we don't want to wait for chars */ + if (port->rxtimeout == 0) + return EOF; + ticks_t start_time = timer_clock(); #endif /* Wait while buffer is empty */ @@ -184,21 +183,21 @@ static int ser_getchar(struct Serial *port) return (int)(unsigned char)fifo_pop_locked(&port->rxfifo); } -#if 0 /** - * Preleva un carattere dal buffer di ricezione. - * Se il buffer e' vuoto, ser_getchar_nowait() ritorna - * immediatamente EOF. + * Fetch a character from the rx FIFO buffer. + * If the buffer is empty, ser_getchar_nowait() returns + * EOF immediatly. + * \note Deprecated, use ser_getchar with rx_timeout set to 0. */ -int ser_getchar_nowait(struct Serial *port) +int ser_getchar_nowait(struct KFileSerial *fd) { - if (fifo_isempty_locked(&port->rxfifo)) + if (fifo_isempty_locked(&fd->ser->rxfifo)) return EOF; /* NOTE: the double cast prevents unwanted sign extension */ - return (int)(unsigned char)fifo_pop_locked(&port->rxfifo); + return (int)(unsigned char)fifo_pop_locked(&fd->ser->rxfifo); } -#endif + /** @@ -213,7 +212,7 @@ static size_t ser_read(struct KFile *fd, void *_buf, size_t size) size_t i = 0; char *buf = (char *)_buf; int c; - + while (i < size) { if ((c = ser_getchar(fds->ser)) == EOF) @@ -345,7 +344,7 @@ void ser_purgeTx(struct KFileSerial *fd) static int ser_flush(struct KFile *fd) { KFileSerial *fds = KFILESERIAL(fd); - + /* * Wait until the FIFO becomes empty, and then until the byte currently in * the hardware register gets shifted out. @@ -366,6 +365,7 @@ static int ser_flush(struct KFile *fd) /** * Initialize a serial port. * + * \param fd KFile Serial struct interface. * \param unit Serial unit to open. Possible values are architecture dependant. */ static struct Serial *ser_open(struct KFileSerial *fd, unsigned int unit) @@ -467,17 +467,32 @@ void ser_init(struct KFileSerial *fds, unsigned int unit) * Since we are master, we have to trigger slave by sending * fake chars on the bus. */ -static size_t spimaster_read(struct KFile *fd, void *buf, size_t size) +static size_t spimaster_read(struct KFile *fd, void *_buf, size_t size) { KFileSerial *fd_spi = KFILESERIAL(fd); ser_flush(&fd_spi->fd); ser_purgeRx(fd_spi); - for (size_t i = 0; i < size; i++) + size_t total_rd = 0; + uint8_t *buf = (uint8_t *)_buf; + int c; + + while (size--) + { + /* + * Send and receive chars 1 by 1, otherwise the rxfifo + * will overrun. + */ ser_putchar(0, fd_spi->ser); - return ser_read(&fd_spi->fd, buf, size); + if ((c = ser_getchar(fd_spi->ser)) == EOF) + break; + + *buf++ = c; + total_rd++; + } + return total_rd; } /** @@ -486,7 +501,7 @@ static size_t spimaster_read(struct KFile *fd, void *buf, size_t size) static size_t spimaster_write(struct KFile *fd, const void *buf, size_t size) { KFileSerial *fd_spi = KFILESERIAL(fd); - + ser_purgeRx(fd_spi); return ser_write(&fd_spi->fd, buf, size);