Serial enhancements: interruptible receive handler and 8 bit serial status for AVR...
authoraleph <aleph@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 2 Jun 2004 21:35:24 +0000 (21:35 +0000)
committeraleph <aleph@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 2 Jun 2004 21:35:24 +0000 (21:35 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@8 38d2e660-2303-0410-9eaa-f027e97ec537

drv/ser.c
drv/ser.h
drv/ser_avr.c

index 6d16b93c1b5dc685b4d0df0c9885e625efad42b1..9d86c23aedc771e890dc40a4775be41266ffcf04 100755 (executable)
--- a/drv/ser.c
+++ b/drv/ser.c
@@ -28,6 +28,9 @@
 
 /*
  * $Log$
+ * Revision 1.3  2004/06/02 21:35:24  aleph
+ * Serial enhancements: interruptible receive handler and 8 bit serial status for AVR; remove volatile attribute to FIFOBuffer, useless for new fifobuf routens
+ *
  * Revision 1.2  2004/05/23 18:21:53  bernie
  * Trim CVS logs and cleanup header info.
  *
@@ -346,5 +349,5 @@ void ser_close(struct Serial *port)
 
        port->is_open = false;
        port->hw->table->cleanup(port->hw);
-       port->hw = NULL;        
+       port->hw = NULL;
 }
index 9d584a8091d93f703d1809693abbf2690e4b7e89..20ac32531f67aca2e49c02e598086615936946ac 100755 (executable)
--- a/drv/ser.h
+++ b/drv/ser.h
@@ -14,6 +14,9 @@
 
 /*
  * $Log$
+ * Revision 1.3  2004/06/02 21:35:24  aleph
+ * Serial enhancements: interruptible receive handler and 8 bit serial status for AVR; remove volatile attribute to FIFOBuffer, useless for new fifobuf routens
+ *
  * Revision 1.2  2004/05/23 18:21:53  bernie
  * Trim CVS logs and cleanup header info.
  *
@@ -36,6 +39,8 @@
  */
 /*\{*/
 #if defined(__AVR__)
+       typedef uint8_t serstatus_t;
+
        /* Software errors */
        #define SERRF_RXFIFOOVERRUN  BV(0)  /*!< Rx FIFO buffer overrun */
        #define SERRF_RXTIMEOUT      BV(5)  /*!< Receive timeout */
@@ -46,6 +51,8 @@
        #define SERRF_FRAMEERROR     BV(4)  /*!< Stop bit missing */
        #define SERRF_PARITYERROR    BV(7)  /*!< Parity error */
 #elif defined(__m56800__)
+       typedef uint16_t serstatus_t;
+
        /* Software errors */
        #define SERRF_RXFIFOOVERRUN  BV(0)  /*!< Rx FIFO buffer overrun */
        #define SERRF_RXTIMEOUT      BV(1)  /*!< Receive timeout */
@@ -117,8 +124,8 @@ struct Serial
         *
         * \{
         */
-       volatile FIFOBuffer txfifo;
-       volatile FIFOBuffer     rxfifo;
+       FIFOBuffer txfifo;
+       FIFOBuffer rxfifo;
        unsigned char txbuffer[CONFIG_SER_TXBUFSIZE];
        unsigned char rxbuffer[CONFIG_SER_RXBUFSIZE];
        /* \} */
@@ -131,8 +138,8 @@ struct Serial
 #endif
 
        /*! Holds the flags defined above.  Will be 0 when no errors have occurred. */
-       REGISTER uint16_t status;
-
+       serstatus_t status;
+       
        /*! Low-level interface to hardware. */
        struct SerialHardware* hw;
 };
index af780c117c6c54968e22e69b1ed8bbdaa28fbfb8..5f789ef1dd11b9f4def878c42b2f1577b891d06c 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*
  * $Log$
+ * Revision 1.3  2004/06/02 21:35:24  aleph
+ * Serial enhancements: interruptible receive handler and 8 bit serial status for AVR; remove volatile attribute to FIFOBuffer, useless for new fifobuf routens
+ *
  * Revision 1.2  2004/05/23 18:21:53  bernie
  * Trim CVS logs and cleanup header info.
  *
@@ -284,7 +287,13 @@ SIGNAL(SIG_UART1_DATA)
 
 
 /*!
- * Serial 0 RX complete interrupt handler
+ * Serial 0 RX complete interrupt handler.
+ *
+ * This handler is interruptible.
+ * Interrupt are reenabled as soon as recv complete interrupt is
+ * disabled. Using INTERRUPT() is troublesome when the serial
+ * is heavily loaded, because and interrupt could be retriggered
+ * when executing the handler prologue before RXCIE is disabled.
  */
 #ifdef __AVR_ATmega103__
 SIGNAL(SIG_UART_RECV)
@@ -292,6 +301,10 @@ SIGNAL(SIG_UART_RECV)
 SIGNAL(SIG_UART0_RECV)
 #endif
 {
+       /* Disable Recv complete IRQ */
+       UCR &= ~BV(RXCIE);
+       ENABLE_INTS;
+
        /* Should be read before UDR */
        ser_handles[SER_UART0].status |= USR & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
 
@@ -311,14 +324,26 @@ SIGNAL(SIG_UART0_RECV)
                        RTS_OFF;
 #endif
        }
+       /* Reenable receive complete int */
+       UCR |= BV(RXCIE);
 }
 
 /*!
- * Serial 1 RX complete interrupt handler
+ * Serial 1 RX complete interrupt handler.
+ *
+ * This handler is interruptible.
+ * Interrupt are reenabled as soon as recv complete interrupt is
+ * disabled. Using INTERRUPT() is troublesome when the serial
+ * is heavily loaded, because and interrupt could be retriggered
+ * when executing the handler prologue before RXCIE is disabled.
  */
 #ifndef __AVR_ATmega103__
 SIGNAL(SIG_UART1_RECV)
 {
+       /* Disable Recv complete IRQ */
+       UCSR0B &= ~BV(RXCIE);
+       ENABLE_INTS;
+
        /* Should be read before UDR */
        ser_handles[SER_UART1].status |= UCSR1A & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
 
@@ -337,6 +362,8 @@ SIGNAL(SIG_UART1_RECV)
                        RTS_OFF;
 #endif
        }
+       /* Reenable receive complete int */
+       UCSR0B |= BV(RXCIE);
 }
 #endif /* !__AVR_ATmega103__ */