Skip to content

NRF52: serial_api: Use polling for putc #8048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 7 additions & 21 deletions targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,7 @@ int serial_getc(serial_t *obj)
*/
void serial_putc(serial_t *obj, int character)
{
bool done = false;
MBED_ASSERT(obj);

#if DEVICE_SERIAL_ASYNCH
Expand All @@ -1449,35 +1450,20 @@ void serial_putc(serial_t *obj, int character)

int instance = uart_object->instance;

/**
* 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.
*/
bool mutex = false;

do {
uint8_t expected = 0;
uint8_t desired = 1;

mutex = core_util_atomic_cas_u8((uint8_t *) &nordic_nrf5_uart_state[instance].tx_in_progress, &expected, desired);
} while (mutex == false);

/* Take ownership and configure UART if necessary. */
nordic_nrf5_serial_configure(obj);

/* Arm Tx DMA buffer. */
nordic_nrf5_uart_state[instance].tx_data = character;
nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[instance],
&nordic_nrf5_uart_state[instance].tx_data,
1);

/* Clear ENDTX event and enable interrupts. */
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);

/* Trigger DMA transfer. */
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance],
NRF_UARTE_TASK_STARTTX);
do {
done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
} while(done == false);

nrf_uarte_event_extra_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
}

/** Check if the serial peripheral is readable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ __STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_eve
*/
__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);

/**
* @brief Function for checking the state of a specific extra UARTE event.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] event Event to check.
*
* @retval True if event is set, False otherwise.
*/
__STATIC_INLINE bool nrf_uarte_event_extra_check(NRF_UARTE_Type * p_reg, uint32_t event);

/**
* @brief Function for clearing a specific extra UARTE event.
*
* @param[in] p_reg Pointer to the peripheral registers structure.
* @param[in] event Extra event to clear.
*/

__STATIC_INLINE void nrf_uarte_event_extra_clear(NRF_UARTE_Type * p_reg, uint32_t event);

/**
* @brief Function for returning the address of a specific UARTE event register.
*
Expand Down Expand Up @@ -456,11 +475,25 @@ __STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_eve

}

__STATIC_INLINE void nrf_uarte_event_extra_clear(NRF_UARTE_Type * p_reg, uint32_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif

}
__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}

__STATIC_INLINE bool nrf_uarte_event_extra_check(NRF_UARTE_Type * p_reg, uint32_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}

__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event)
{
Expand Down