Skip to content
Snippets Groups Projects
Commit a7c33fea authored by Sandeep Mistry's avatar Sandeep Mistry Committed by Sandeep Mistry
Browse files

UART: manually handle IRQ if DRE + interrupts disabled or in higher priority ISR

When write is called and TX buffer is full.
parent ee913a08
No related branches found
No related tags found
No related merge requests found
......@@ -688,7 +688,7 @@ void SERCOM::initClockNVIC( void )
// Setting NVIC
NVIC_EnableIRQ(IdNvic);
NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
NVIC_SetPriority (IdNvic, SERCOM_NVIC_PRIORITY); /* set Priority */
//Setting clock
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
......
......@@ -21,7 +21,8 @@
#include "sam.h"
#define SERCOM_FREQ_REF 48000000
#define SERCOM_FREQ_REF 48000000
#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1)
typedef enum
{
......
......@@ -154,7 +154,27 @@ size_t Uart::write(const uint8_t data)
if (sercom->isDataRegisterEmptyUART() && txBuffer.available() == 0) {
sercom->writeDataUART(data);
} else {
while(txBuffer.isFull()); // spin lock until a spot opens up in the buffer
// spin lock until a spot opens up in the buffer
while(txBuffer.isFull()) {
uint8_t interruptsEnabled = ((__get_PRIMASK() & 0x1) == 0);
if (interruptsEnabled) {
uint32_t exceptionNumber = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
if (exceptionNumber == 0 ||
NVIC_GetPriority((IRQn_Type)(exceptionNumber - 16)) > SERCOM_NVIC_PRIORITY) {
// no exception or called from an ISR with lower priority,
// wait for free buffer spot via IRQ
continue;
}
}
// interrupts are disabled or called from ISR with higher or equal priority than the SERCOM IRQ
// manually call the UART IRQ handler when the data register is empty
if (sercom->isDataRegisterEmptyUART()) {
IrqHandler();
}
}
txBuffer.store_char(data);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment