|
26 | 26 | #if DEVICE_SERIAL |
27 | 27 |
|
28 | 28 | #include "serial_api.h" |
| 29 | +#include "mbed_wait_api.h" |
29 | 30 |
|
30 | 31 | #include "mbed_assert.h" |
31 | 32 | #include "PeripheralPins.h" |
@@ -142,7 +143,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) |
142 | 143 | obj->serial.uart_control->cfg.ui32RxBufferSize = 0; |
143 | 144 | obj->serial.uart_control->cfg.ui32TxBufferSize = 0; |
144 | 145 |
|
145 | | - obj->serial.uart_control->cfg.ui32FifoLevels = AM_HAL_UART_RX_FIFO_7_8; |
| 146 | + // Mbed expects an interrupt whenever we have at least one char in the Rx FIFO. |
| 147 | + obj->serial.uart_control->cfg.ui32FifoLevels = AM_HAL_UART_RX_FIFO_1_8; |
146 | 148 |
|
147 | 149 | // start UART instance |
148 | 150 | MBED_ASSERT(am_hal_uart_initialize(uart, &(obj->serial.uart_control->handle)) == AM_HAL_STATUS_SUCCESS); |
@@ -244,6 +246,7 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) |
244 | 246 | break; |
245 | 247 | } |
246 | 248 | // NVIC_SetVector(uart_irqs[obj->serial.index], vector); |
| 249 | + NVIC_ClearPendingIRQ((IRQn_Type)(UART0_IRQn + obj->serial.uart_control->inst)); |
247 | 250 | NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + obj->serial.uart_control->inst)); |
248 | 251 | } else { // disable |
249 | 252 | switch (irq) { |
@@ -275,6 +278,20 @@ int serial_getc(serial_t *obj) |
275 | 278 |
|
276 | 279 | do { |
277 | 280 | am_hal_uart_transfer(obj->serial.uart_control->handle, &am_hal_uart_xfer_read_single); |
| 281 | + |
| 282 | + // Seeing very odd behavior with this uart, where digital glitches on the line can cause the |
| 283 | + // framing error bit to set and then cause at least some of the data within the Rx FIFO to be |
| 284 | + // deleted. This causes an infinite hang, as Mbed requires serial_getc() to return a character |
| 285 | + // if serial_readable() returns true. This UART is not well documented, so unable to say if this |
| 286 | + // is an errata or some sort of odd design choice. |
| 287 | + // To avoid this, if we did not get any data and the framing error bit is set, simply clear the flag |
| 288 | + // and return an arbitrary character. This is a little awkward but prevents a hard-to-debug hang. |
| 289 | + if(bytes_read == 0 && UARTn(obj->serial.uart_control->inst)->RSR_b.FESTAT) |
| 290 | + { |
| 291 | + UARTn(obj->serial.uart_control->inst)->RSR_b.FESTAT = 0; |
| 292 | + return 'x'; |
| 293 | + } |
| 294 | + |
278 | 295 | } while (bytes_read == 0); |
279 | 296 |
|
280 | 297 | return (int)rx_c; |
@@ -372,6 +389,8 @@ const PinMap *serial_rts_pinmap(void) |
372 | 389 | } |
373 | 390 | #endif |
374 | 391 |
|
| 392 | +static volatile uint32_t foo = 0; |
| 393 | + |
375 | 394 | static inline void uart_irq(uint32_t instance) |
376 | 395 | { |
377 | 396 | void *handle = ap3_uart_control[instance].handle; |
|
0 commit comments