Hi, I just received my first NXP development board (FRDM-K66F). I am trying to create a CDC device (ACM), and I am trying to get the UART communication working at a rate of 6Mbaud.
From what I can see from the documentation, my baud rate maximum will be baud = clock / 16.
I am using UART0, and I *think* I have correctly linked it to the system clock. The documentation indicates that the system clock is running at 120Mhz, and stepping through the code confirms this value as I pass it to the UART_Init. Based on this information and the baud calculation above, I should have no problems communicating at 7.5Mbaud.
I used the dev_cdc_vcom_freertos_frdmk66f example as a baseline. This example creates the CDC device that I need, but it is set up as a loopback, so I needed to integrate pieces from the freertos_uart_frdmk66f for setting up my UART0.
The uart example is pretty basic, so I used the K66F Reference guide to try to set up the UART correctly (this may be my problem). The original cdc_vcom code had the debug output also using UART0, so I have redirected that debug output to UART1.
The best data rate I can achieve is 1Mbaud. If I try to go faster than that, I get garbage characters in my terminal. I have confirmed that my terminal can handle the high 6Mbaud rates with my host device, so I do not have reason to believe that my terminal is the problem.
My code is still pretty basic, so I thought maybe someone would spot what I have done wrong. Again, the base source is from the dev_cdc_vcom_freertos_frdmk66f example, so I will just post the portion that I have modified.
// -----------------
// In virtual_com.h
// -----------------
#define LINE_CODING_DTERATE (6000000)
// -----------------
// In virtual_com.c
// -----------------
#define UART_BASE UART0
#define UART_RX_TX_IRQn UART0_RX_TX_IRQn
/* UART configuration */
struct rtos_uart_config uart_config = {
.baudrate = LINE_CODING_DTERATE,
.parity = kUART_ParityDisabled,
.stopbits = kUART_OneStopBit,
.buffer = s_uartBackgroundBuffer,
.buffer_size = sizeof(s_uartBackgroundBuffer),
};
.
.
.
void CdcTask(void *handle)
{
int error = kStatus_Fail;
USB_DeviceApplicationInit();
while (1)
{
if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
if (s_cdcRecvSize > 0)
{
error = UART_RTOS_Send(&s_uartHandle, s_cdcRecvBuf, s_cdcRecvSize);
if (error != kStatus_Success)
{
/* Failure to send Data Handling code here */
PRINTF("UART Send Error");
}
s_cdcRecvSize = 0;
// Re-arm the receive handler.
USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle,
USB_CDC_VCOM_BULK_OUT_ENDPOINT,
s_cdcRecvBuf,
g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);
}
}
}
}
void UartTask(void *pvParameters)
{
uint8_t uartRxByte = 0;
size_t rxCount;
usb_status_t error = kStatus_USB_Error;
uart_config.srcclk = CLOCK_GetFreq(kCLOCK_CoreSysClk);
uart_config.base = UART_BASE;
if (0 > UART_RTOS_Init(&s_uartHandle, &t_uartHandle, &uart_config))
{
PRINTF("Error during UART initialization.\r\n");
vTaskSuspend(NULL);
}
while(1)
{
UART_RTOS_Receive(&s_uartHandle, &uartRxByte, sizeof(uartRxByte), &rxCount);
if (rxCount > 0)
{
error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle,
USB_CDC_VCOM_BULK_IN_ENDPOINT, &uartRxByte, sizeof(uartRxByte));
if (error != kStatus_USB_Success)
{
// Failure to send Data Handling code here
PRINTF("CDC Send Error");
}
rxCount = 0;
}
}
}
int main(void)
{
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
NVIC_SetPriority(UART_RX_TX_IRQn, 5);
if (xTaskCreate(CdcTask, // pointer to the task
s_cdcTaskName, // task name for kernel awareness debugging
1000L / sizeof(portSTACK_TYPE), // task stack size
&s_cdcVcom, // optional task startup argument
5, // initial priority
&s_cdcVcom.applicationTaskHandle // optional task handle to create
) != pdPASS)
{
usb_echo("CDC task create failed!\r\n");
return -1;
}
if (xTaskCreate(UartTask, // pointer to the task
s_uartTaskName, // task name for kernel awareness debugging
1000L / sizeof(portSTACK_TYPE), // task stack size
NULL, // optional task startup argument
5, // initial priority
NULL // optional task handle to create
) != pdPASS)
{
usb_echo("UART task create failed!\r\n");
return -11;
}
vTaskStartScheduler();
return 1;
}
A few more things to note... as I step through the UART_RTOS_Init (which leads to the UART_Init), I can see that the srcClock_Hz gets set to 120000000, I see that the sbr gets set to 1, the config->baudRate_Bps comes in as my defined 6000000, and the brfa is calculated as 8. Based on the calculation that I found in the reference manual in section
59.5.3 Baud Rate Generation
UART baud rate = UART module clock / (16 × (SBR[12:0] + BRFD))
... plugging in the above values would give me the 6000000 that I want. It just doesn't seem to communicate correctly.
Does anyone see something that I missed? Thanks for your help!