88
88
#define UART1_FIFO_BUFFER_SIZE MBED_CONF_NORDIC_UART_1_FIFO_SIZE
89
89
#define DMA_BUFFER_SIZE 1
90
90
#define NUMBER_OF_BANKS 2
91
+ #define FIFO_MIN 3
91
92
92
93
/***
93
94
* _______ _ __
@@ -144,8 +145,10 @@ typedef struct {
144
145
bool callback_posted ;
145
146
uint8_t active_bank ;
146
147
nrf_atfifo_t * fifo ;
148
+ uint32_t fifo_free_count ;
147
149
nrf_ppi_channel_t ppi_rts ;
148
150
nrf_drv_gpiote_pin_t rts ;
151
+ bool rx_suspended ;
149
152
} nordic_uart_state_t ;
150
153
151
154
/**
@@ -434,6 +437,7 @@ static void nordic_nrf5_uart_event_handler_endrx(int instance)
434
437
/* Copy 1 byte from DMA buffer and commit to FIFO buffer. */
435
438
* byte = nordic_nrf5_uart_state [instance ].buffer [active_bank ][index ];
436
439
nrf_atfifo_item_put (nordic_nrf5_uart_state [instance ].fifo , & fifo_context );
440
+ core_util_atomic_decr_u32 (& nordic_nrf5_uart_state [instance ].fifo_free_count , 1 );
437
441
438
442
} else {
439
443
@@ -463,9 +467,15 @@ static void nordic_nrf5_uart_event_handler_rxstarted(int instance)
463
467
uint8_t next_bank = nordic_nrf5_uart_state [instance ].active_bank ^ 0x01 ;
464
468
465
469
nrf_uarte_rx_buffer_set (nordic_nrf5_uart_register [instance ], nordic_nrf5_uart_state [instance ].buffer [next_bank ], DMA_BUFFER_SIZE );
466
- /* Clear rts if flow control is enabled since we are ready to recieve the next byte */
467
- if (nordic_nrf5_uart_state [instance ].owner -> rts != NRF_UART_PSEL_DISCONNECTED ) {
468
- nrf_drv_gpiote_clr_task_trigger ((nrf_drv_gpiote_pin_t )nordic_nrf5_uart_state [instance ].owner -> rts );
470
+ if (nordic_nrf5_uart_state [instance ].rts != NRF_UART_PSEL_DISCONNECTED ) {
471
+ if (nordic_nrf5_uart_state [instance ].fifo_free_count > FIFO_MIN ) {
472
+ /* Clear rts since we are ready to receive the next byte */
473
+ nrf_drv_gpiote_clr_task_trigger (nordic_nrf5_uart_state [instance ].rts );
474
+ } else {
475
+ /* Suspend reception since there isn't enough buffer space.
476
+ * The function serial_getc will restart reception. */
477
+ nordic_nrf5_uart_state [instance ].rx_suspended = true;
478
+ }
469
479
}
470
480
}
471
481
@@ -697,6 +707,7 @@ static void nordic_nrf5_uart_configure_rx(int instance)
697
707
698
708
/* Clear FIFO buffer. */
699
709
nrf_atfifo_clear (nordic_nrf5_uart_state [instance ].fifo );
710
+ nordic_nrf5_uart_state [instance ].fifo_free_count = UART0_FIFO_BUFFER_SIZE ;
700
711
701
712
/* Clear Rx related events. */
702
713
nrf_uarte_event_clear (nordic_nrf5_uart_register [instance ], NRF_UARTE_EVENT_RXSTARTED );
@@ -716,6 +727,9 @@ static void nordic_nrf5_uart_configure_rx(int instance)
716
727
/* Set non-asynchronous mode. */
717
728
nordic_nrf5_uart_state [instance ].rx_asynch = false;
718
729
730
+ /* Clear suspend condition */
731
+ nordic_nrf5_uart_state [instance ].rx_suspended = false;
732
+
719
733
/* Enable interrupts again. */
720
734
nrf_uarte_int_enable (nordic_nrf5_uart_register [instance ], NRF_UARTE_INT_RXSTARTED_MASK |
721
735
NRF_UARTE_INT_ENDRX_MASK );
@@ -743,6 +757,9 @@ static void nordic_nrf5_uart_configure_rx_asynch(int instance)
743
757
/* Set asynchronous mode. */
744
758
nordic_nrf5_uart_state [instance ].rx_asynch = true;
745
759
760
+ /* Clear suspend condition */
761
+ nordic_nrf5_uart_state [instance ].rx_suspended = false;
762
+
746
763
/* Enable Rx interrupt. */
747
764
nrf_uarte_int_enable (nordic_nrf5_uart_register [instance ], NRF_UARTE_INT_ENDRX_MASK );
748
765
}
@@ -1304,6 +1321,11 @@ int serial_getc(serial_t *obj)
1304
1321
nrf_atfifo_item_get_t context ;
1305
1322
uint8_t * byte = (uint8_t * ) nrf_atfifo_item_get (fifo , & context );
1306
1323
nrf_atfifo_item_free (fifo , & context );
1324
+ core_util_atomic_incr_u32 (& nordic_nrf5_uart_state [instance ].fifo_free_count , 1 );
1325
+ if (nordic_nrf5_uart_state [instance ].rx_suspended ) {
1326
+ nordic_nrf5_uart_state [instance ].rx_suspended = false;
1327
+ nrf_drv_gpiote_clr_task_trigger (nordic_nrf5_uart_state [instance ].rts );
1328
+ }
1307
1329
1308
1330
return * byte ;
1309
1331
}
0 commit comments