Hello,
I have a bare metal K40 project that uses the scatter/gather DMA function in conjunction with UART0 to receive serial data. This all works fine.
However I am not able to successfully change the BPS rate on UART0 after it has been operating.
I have an external WiFi module that has an initial bps rate (115200). But can be changed on the fly.
I issue the command to the WiFi module to change to a bps rate to 2000000. Wait for all bytes to be transmitted from the K40 then change the bps rate of UART0. Here is the code I use to change the bps rate
//-----------------------------------------------------------------------------
void UART0_SetBpsRate(int nBpsRate)
{
uint8_t temp;
unsigned int sbr, brfa;
// To update the 13-bit baud rate setting (SBR[12:0]), first write to BDH to
// buffer the high half of the new value and then write to BDL. The working value in BDH
// does not change until BDL is written.
// Calculate baud settings
sbr = (SystemCoreClock / (nBpsRate * 16));
// UART0_BDH: LBKDIE=0, RXEDGIE=0.
UART0->BDH = (sbr & 0x1F00) >> 8;
// UART0_BDL
UART0->BDL = sbr & 0xFF; //0x34U;
// Determine if a fractional divider is needed to get closer to the baud rate
brfa = (((SystemCoreClock * 32) / (nBpsRate * 16)) - (sbr * 32)); //=> 8 for 100Mhz and 2 for 96Mhz
temp = UART0->C4 & ~(0x1F);
// UART0_C4: MAEN1=0, MAEN2=0, M10=0, BRFA=0
UART0->C4 = temp | brfa;
}
However after changing the rate I no longer receive data from UART0/DMA.
I verified with a logic analyzer that the WiFi module has changed rates and is transmitting.
Any suggestions?
Thanks,
Mike
Hi
Ensure that any rx errors (like framing error) that may occur during the baud rate change are cleared in the status register since reception is blocked when they are set.
Also when receiving with DMA you still need an rx error interrupt handler to clear such flags if ever they were to occur in normal operation.
It may also be a good idea to disable the receiver when changing and re-enabling it again in case you don't already do it.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements
For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/kinetis/TWR-K40D100M.html
Hello,
I did refer to the sdk example. As mentioned I am not having trouble setting the bps rate. That works fine. The problem is in changing the bps after DMA transfer has been enabled.
Mike
Setting the bps rate is not the problem. The following works
InitUART();
SetBps(2000000);
InitDMA();
communication works fine. I verified the bps rate with a logic analyzer. The following does not
InitUART();
SetBps(115200);
InitDMA();
SetBps(2000000);
I can see byte transmissions at the 2Mbps rate. However anything sent from the external device does not generate DMA transfers.
Hello
I suggest you check the function UART_Init() of the SDK. In that function, you have the steps to calculate the register values to reach the desired baud-rate.
You may refer to that and integrate it into your code.
Let me know if this is helpful, if you have more questions do not hesitate to ask me.
Best regards,
Omar