Merge pull request #9616 from kjbracey-arm/nrf52_atomics

nRF52 serial: Tighten/simplify atomics
pull/9781/head
Cruz Monrreal 2019-02-20 11:58:34 -06:00 committed by GitHub
commit 59549b8eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 22 deletions

View File

@ -139,8 +139,8 @@ typedef struct {
uint8_t buffer[NUMBER_OF_BANKS][DMA_BUFFER_SIZE]; uint8_t buffer[NUMBER_OF_BANKS][DMA_BUFFER_SIZE];
uint32_t usage_counter; uint32_t usage_counter;
uint8_t tx_data; uint8_t tx_data;
volatile uint8_t tx_in_progress; bool tx_in_progress;
volatile uint8_t rx_in_progress; bool rx_in_progress;
bool tx_asynch; bool tx_asynch;
bool rx_asynch; bool rx_asynch;
bool callback_posted; bool callback_posted;
@ -253,7 +253,7 @@ static void nordic_nrf5_uart_callback_handler(uint32_t instance)
static void nordic_nrf5_uart_event_handler_endtx(int instance) static void nordic_nrf5_uart_event_handler_endtx(int instance)
{ {
/* Release mutex. As the owner this call is safe. */ /* Release mutex. As the owner this call is safe. */
nordic_nrf5_uart_state[instance].tx_in_progress = 0; core_util_atomic_store_bool(&nordic_nrf5_uart_state[instance].tx_in_progress, false);
/* Check if callback handler and Tx event mask is set. */ /* Check if callback handler and Tx event mask is set. */
uart_irq_handler callback = (uart_irq_handler) nordic_nrf5_uart_state[instance].owner->handler; uart_irq_handler callback = (uart_irq_handler) nordic_nrf5_uart_state[instance].owner->handler;
@ -276,8 +276,8 @@ static void nordic_nrf5_uart_event_handler_endtx(int instance)
static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance) static void nordic_nrf5_uart_event_handler_endtx_asynch(int instance)
{ {
/* Set Tx done and reset Tx mode to be not asynchronous. */ /* Set Tx done and reset Tx mode to be not asynchronous. */
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
nordic_nrf5_uart_state[instance].tx_asynch = false; nordic_nrf5_uart_state[instance].tx_asynch = false;
core_util_atomic_store_bool(&nordic_nrf5_uart_state[instance].tx_in_progress, false);
/* Cast handler to callback function pointer. */ /* Cast handler to callback function pointer. */
void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->tx_handler; void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->tx_handler;
@ -483,8 +483,8 @@ static void nordic_nrf5_uart_event_handler_rxstarted(int instance)
static void nordic_nrf5_uart_event_handler_endrx_asynch(int instance) static void nordic_nrf5_uart_event_handler_endrx_asynch(int instance)
{ {
/* Set Rx done and reset Rx mode to be not asynchronous. */ /* Set Rx done and reset Rx mode to be not asynchronous. */
nordic_nrf5_uart_state[instance].rx_in_progress = 0;
nordic_nrf5_uart_state[instance].rx_asynch = false; nordic_nrf5_uart_state[instance].rx_asynch = false;
core_util_atomic_store_bool(&nordic_nrf5_uart_state[instance].rx_in_progress, false);
/* Cast handler to callback function pointer. */ /* Cast handler to callback function pointer. */
void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->rx_handler; void (*callback)(void) = (void (*)(void)) nordic_nrf5_uart_state[instance].owner->rx_handler;
@ -1411,7 +1411,7 @@ int serial_writable(serial_t *obj)
int instance = uart_object->instance; int instance = uart_object->instance;
return ((nordic_nrf5_uart_state[instance].tx_in_progress == 0) && return (!core_util_atomic_load_bool(&nordic_nrf5_uart_state[instance].tx_in_progress) &&
(nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY))); (nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY)));
} }
@ -1470,16 +1470,14 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx
/** /**
* tx_in_progress acts like a mutex to ensure only one transmission can be active at a time. * tx_in_progress acts like a mutex to ensure only one transmission can be active at a time.
* The flag is modified using the atomic compare-and-set function. * The flag is modified using the atomic exchange function - only proceed when we see the
* flag clear and we set it to true.
*/ */
bool mutex = false; bool old_mutex;
do { do {
uint8_t expected = 0; old_mutex = core_util_atomic_exchange_bool(&nordic_nrf5_uart_state[instance].tx_in_progress, true);
uint8_t desired = 1; } while (old_mutex == true);
mutex = core_util_atomic_cas_u8((uint8_t *) &nordic_nrf5_uart_state[instance].tx_in_progress, &expected, desired);
} while (mutex == false);
/* State variables. */ /* State variables. */
int result = 0; int result = 0;
@ -1596,16 +1594,14 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
/** /**
* rx_in_progress acts like a mutex to ensure only one asynchronous reception can be active at a time. * rx_in_progress acts like a mutex to ensure only one asynchronous reception can be active at a time.
* The flag is modified using the atomic compare-and-set function. * The flag is modified using the atomic exchange function - only proceed when we see the
* flag clear and we set it to true.
*/ */
bool mutex = false; bool old_mutex;
do { do {
uint8_t expected = 0; old_mutex = core_util_atomic_exchange_bool(&nordic_nrf5_uart_state[instance].rx_in_progress, true);
uint8_t desired = 1; } while (old_mutex == true);
mutex = core_util_atomic_cas_u8((uint8_t *) &nordic_nrf5_uart_state[instance].rx_in_progress, &expected, desired);
} while (mutex == false);
/* Store callback handler, mask and reset event value. */ /* Store callback handler, mask and reset event value. */
obj->serial.rx_handler = handler; obj->serial.rx_handler = handler;
@ -1684,8 +1680,8 @@ void serial_tx_abort_asynch(serial_t *obj)
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX); nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
/* Reset Tx flags. */ /* Reset Tx flags. */
nordic_nrf5_uart_state[instance].tx_in_progress = 0;
nordic_nrf5_uart_state[instance].tx_asynch = false; nordic_nrf5_uart_state[instance].tx_asynch = false;
nordic_nrf5_uart_state[instance].tx_in_progress = false;
/* Force reconfiguration. */ /* Force reconfiguration. */
obj->serial.update = true; obj->serial.update = true;
@ -1712,8 +1708,8 @@ void serial_rx_abort_asynch(serial_t *obj)
core_util_critical_section_enter(); core_util_critical_section_enter();
/* Reset Rx flags. */ /* Reset Rx flags. */
nordic_nrf5_uart_state[obj->serial.instance].rx_in_progress = 0;
nordic_nrf5_uart_state[obj->serial.instance].rx_asynch = false; nordic_nrf5_uart_state[obj->serial.instance].rx_asynch = false;
nordic_nrf5_uart_state[obj->serial.instance].rx_in_progress = false;
obj->serial.rx_asynch = false; obj->serial.rx_asynch = false;
/* Force reconfiguration. */ /* Force reconfiguration. */