Doc fixes.
[bertos.git] / drv / ser.c
index dbbf9382fbb8eb9c2c42cb92dce0e510c7bb6b6e..0838bc1538855e6c58575d0c6107d16b2981c485 100644 (file)
--- a/drv/ser.c
+++ b/drv/ser.c
 #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
+
 
 
 /**
@@ -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;
 }
 
 /**
@@ -510,3 +525,5 @@ void spimaster_init(KFileSerial *fds, unsigned int unit)
        fds->fd.read = spimaster_read;
        fds->fd.write = spimaster_write;
 }
+
+