@@ -30,6 +30,9 @@ extern "C" {
3030int stdio_uart_inited = 0 ;
3131serial_t stdio_uart ;
3232
33+ static inline void uart0_irq (void );
34+ static inline void uart1_irq (void );
35+
3336void serial_init (serial_t * obj , PinName tx , PinName rx )
3437{
3538 if (tx == STDIO_UART_TX && stdio_uart_inited != 0 ) {
@@ -62,8 +65,15 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
6265 //uart_set_translate_crlf(obj->dev, false);
6366 uart_set_fifo_enabled (obj -> dev , false);
6467
68+ // Prepare interrupt. Note that we set it to enabled here, but the interrupt
69+ // won't fire yet because we haven't enabled any interrupt sources.
70+ int UART_IRQ = obj -> dev == uart0 ? UART0_IRQ : UART1_IRQ ;
71+ irq_set_exclusive_handler (UART_IRQ , obj -> dev == uart0 ? uart0_irq : uart1_irq );
72+ irq_clear (UART_IRQ );
73+ irq_set_enabled (UART_IRQ , true);
74+
6575 if (tx == STDIO_UART_TX ) {
66- memmove (& stdio_uart , obj , sizeof (serial_t ));
76+ memcpy (& stdio_uart , obj , sizeof (serial_t ));
6777 stdio_uart_inited = 1 ;
6878 }
6979}
@@ -102,14 +112,23 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
102112static volatile uart_irq_handler irq_handler ;
103113static volatile uint32_t serial_irq_ids [2 ] = {0 };
104114
105- static inline void uart0_irq (void )
106- {
107- irq_handler (serial_irq_ids [0 ], RxIrq );
115+ static inline void uart0_irq (void ) {
116+ if (uart_is_writable (uart0 )) {
117+ irq_handler (serial_irq_ids [0 ], TxIrq );
118+ }
119+ if (uart_is_readable (uart0 )) {
120+ irq_handler (serial_irq_ids [0 ], RxIrq );
121+ }
108122}
109123
110124static inline void uart1_irq (void )
111125{
112- irq_handler (serial_irq_ids [1 ], RxIrq );
126+ if (uart_is_writable (uart1 )) {
127+ irq_handler (serial_irq_ids [1 ], TxIrq );
128+ }
129+ if (uart_is_readable (uart1 )) {
130+ irq_handler (serial_irq_ids [1 ], RxIrq );
131+ }
113132}
114133
115134void serial_irq_handler (serial_t * obj , uart_irq_handler handler , uint32_t id )
@@ -124,12 +143,14 @@ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
124143
125144void serial_irq_set (serial_t * obj , SerialIrq irq , uint32_t enable )
126145{
127- int UART_IRQ = obj -> dev == uart0 ? UART0_IRQ : UART1_IRQ ;
128-
129- irq_set_exclusive_handler (UART_IRQ , obj -> dev == uart0 ? uart0_irq : uart1_irq );
130- irq_set_enabled (UART_IRQ , enable );
146+ if (irq == RxIrq ) {
147+ obj -> rxIrqEnabled = enable ;
148+ }
149+ else if (irq == TxIrq ) {
150+ obj -> txIrqEnabled = enable ;
151+ }
131152
132- uart_set_irq_enables (obj -> dev , irq == RxIrq , irq == TxIrq );
153+ uart_set_irq_enables (obj -> dev , obj -> rxIrqEnabled , obj -> txIrqEnabled );
133154}
134155
135156int serial_getc (serial_t * obj )
0 commit comments