# max32660 sudden uart slowdown above 3MBaud

I am trying to set up UART1 for debugging on a MAX32660. At various baudrates, I print Hello, world!\n 1000 times, and measure the time elapsed for each case.

140 bits/write,   14 characters/write

921600 baud: 149us / write      93Kcps
2MBaud:       69us / write     203Kcps
3.0MBaud:     47us / write     298Kcps
3.1MBaud:    691us / write      20Kcps
4MBaud:      551us / write      25Kcps
6MBaud:      382us / write      37Kcps


Why does the throughput drop as the baudrate increases above 3MHz?

Measurements are made and reported on the Tx side, and there is no flow control (Flow control is disabled via UART_FLOW_DISABLE in sys_uart_cfg). I am using TMR_TO_Elapsed() to make the measurements, and I checked it against my stopwatch in all cases, so it's not like the UART setting is affecting a common prescaler.

What could explain the sudden 16X transmission slowdown when the baudrate exceeds 3.0 MHz?

Update I hooked up a scope; the baudrate actually seems to be dropping about 16X. So maybe uart.c is not working right?

Update I read out MXC_UART1->baud0. The value is 0x00000001 not 0x00040001. So the value of FACTOR is 0 instead of 4 as expected. This would exactly explain a 16X slowdown. But how can this be? Surely the baudrate code in the eval kit is right?

Per the above observation, perhaps hardware only supports FACTOR <= 3 (though I see nothing about this in the errata).

So I tried changing MAX_FACTOR to 3 in uart.c. While this leads to the correct setting of baud0 and baud1, it appears that hardware runs at a very very slow baudrate if baud0.ibaud==0.

requested baudrate 3.0MHz:
baud0 = 00030001
baud1 = 00000003
actual baudrate: 3.0MHz

requested baudrate 3.1MHz:  (MAX_FACTOR = 4   -- uart.c as shipped from Maxim)
baud0 = 00000001
baud1 = 0000006d
actual baudrate: 200KHz

requested baudrate 3.1MHz:  (MAX_FACTOR = 3   -- uart.c modified)
baud0 = 00030000
baud1 = 00000075
actual baudrate: 1500Hz


I agree with the uart.c output in this last case. According to the user manual, it should yield a baudrate of:

DIV  = ibaud + dbaud/128
= 0 + 0x75 = 0.91
baud = PeriphClk / [DIV * 2^(7-factor)]
= 48MHz / [0.91 * 16] = 3.3MHz


which is the right speed to use, according to the framing error erratum (which itself gives me a great feeling too but enough on that topic).

Yet the observed baudrate (on the scope) is not 3.3MHz, but 1500Hz. Off by a tad.

• How big is your buffer? On the PC side? – DKNguyen Jul 5 '20 at 1:52
• @DKNguyen The measurement is done (and reported) by the Tx side, and there is no flow control, so the receiver buffer can't matter. (The receiver is actually another MAX32660 because I couldn't find a decent serial adapter for Linux.) – personal_cloud Jul 5 '20 at 2:08
• What clock is your MCU being clocked at? And the clock to the UART (not the transmission clock). And how are you feeding the UART? DMA? Or interrupts? Maybe your UART is taking less cycles to transmit everything that the number of cycles processor is taking to keep the UART fed. – DKNguyen Jul 5 '20 at 4:39
• According to the datasheet maximum baud rate is 4000kbaud. Why are you trying to run it at 6Mbaud? "Surely the baudrate code in the eval kit is right?" what code did your eval kit come with? – Bruce Abbott Jul 5 '20 at 5:29
• @Bruce Yeah I saw the 4Mbaud limit too. So forget the 6MBaud point. But 3.1Mbaud should definitely work, right? My eval kit came with "MAX32660 SDK", documentation version 2.7.5.0. – personal_cloud Jul 5 '20 at 5:38