Hi NXP team,
I am developing a UART bootloader using FRDM-KEAZ128Q80. I want to realize a UART2 fifo by software, so i have to use UART2 receiving way by interrupting. But strange time sequence of UART rx interrupt and its flag occurs to me, that is,
1) only one interrupt Rx interrupt(UART2_C2[RIE]: Receiver Interrupt Enable for RDRF) is enabled;
2) program can run to UART2_IRQHandler(UART2 interrupt handle function in uart.c), when I transmit one byte data to board by Tera Term VT(virtual COM tools);
Strange:
3) UART2_S1[RDRF] would be 0, when program enters into UART2_IRQHandler() and use UART_IsRxBuffFull() to query Rx buffer of UART; but if i use UART_GetChar(), the program can get the status of UART2_S1[RDRF] .
Expectation :
when evb receives a uart byte data, then run to uart interrupt handle and get the interrupt flag RDRF==1, but actually it is RDRF==1 if i query the flag at once in interrupt handle.
When i can get the flag set(RDRF == 1)? it seems i have to use a polling loop to wait the flag.
I dont know why ? if i use a while loop in my interrupt handle, i am warried that the loop wasting much time for wating RDRF set and even program will go stuck in the loop especially program cant get the flag set.
Environment and tools
My EVB: FRDM-KEAZ128Q80;
IDE: S32DS for ARM 2018.R1;
MCU PN: S9KEAZ128AMLK;
SDK: 1.0.0
uart driver: uart.c, .h
UART configuration: BUS 20MHz, UART2 baud rate=115200bps, enable receive buffer full interrupt and receive function
My uart configuration:
//uart_manager.c
#define TERMINAL_UART_PORT UART2
void UartManager_Init()
{
UART_ConfigType sUartConfig = {{0}};
sUartConfig.u32SysClkHz = BUS_CLK_FREQ; // 20MHz(20000000)
sUartConfig.u32Baudrate = UART_BIT_BAUDRATE; // 115200kbps
sUartConfig.sctrl1settings.byte = 0;
sUartConfig.sctrl2settings.bits.bTe = 1; // transmitter enable
sUartConfig.sctrl2settings.bits.bRe = 1; // receive enable
sUartConfig.sctrl2settings.bits.bRie = 1; // receive buffer full interrupt enable
UART_SetCallback(TERMINAL_UART_PORT, UartManager_Interrupt);
UART_Init(TERMINAL_UART_PORT, &sUartConfig);
}
void UartManager_Interrupt(void)
{
volatile uint8_t data = 0;
/*only use 1 case (case 1, 2, 3) for test*/
// case 1 - success to read flag RDRF and uart data
// data = UART_GetChar(TERMINAL_UART_PORT); // can get the received char
// case 2 - success to read flag RDRF and uart data
//while(!UART_IsRxBuffFull(TERMINAL_UART_PORT)); // can pass the loop, which means RDRF==1
//data = UART_ReadDataReg(TERMINAL_UART_PORT);
// case 3 - failure to read flag RDRF and uart data
/* if(UART_IsRxBuffFull(TERMINAL_UART_PORT)){ // cant get the flag RDRF == 1, it will run to else condition
data = UART_ReadDataReg(TERMINAL_UART_PORT);
}
else
{
UART_ReadDataReg(TERMINAL_UART_PORT);
}*/
}
Hi,
In the following link you can find some FRDM examples, the one called FRDM_KEA128_UART_Interrupt has an implementation using the UART2.
I hope this helps you.
Best Regards,
Alexis Andalon
Hi
Serial loaders for the KEA128 (Kboot compatible or iHex, SREC) including robust SW FIFO interrupt/DMA driven driver, documented and industrially proven, are readily available at
http://www.utasker.com/kinetis/FRDM-KEAZ128Q80.html
http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf
http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
Open Source at GITHUB and can be used on almost any Kinetis part, on any UART/LPUART and with any IDE without any porting work: https://github.com/uTasker/uTasker-Kinetis
If you are doing an educational project where you need to redevelop for learning purposes you can use the project to simulate the chip and its UART/interrupt operation and copy relevant parts to solve issues with initial code.
Regards
Mark