KL 17 LPUART DMA - RX only 1 byte.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KL 17 LPUART DMA - RX only 1 byte.

582 Views
mitchell7man
Contributor I

I'm having issues receiving data on LPUART 0. Send works fine. Is my configuration correct, or what else might be going wrong? (Note the rx function is called 1 byte at a time at first as I am reading xbee frames). I am expecting to read the data in TX (see capture below).response.png 

My set-up code.

void XBEE_UART_INIT_PERIPHERALS()
{
// Init power pin
GPIO_PinInit(XBEE_UART_POW_ENABLE, &xbee_power);
XBEE_SET_POWER_ON(false); // Start with power off.
// Init CTS and RTS
GPIO_PinInit(XBEE_UART_CTS, &xbee_cts);
GPIO_PinInit(XBEE_UART_RTS, &xbee_rts);
GPIO_PinWrite(XBEE_UART_CTS, false); // negative logic -- so false signals xbee that it is clear to send
// Init _RST and AWAKE
GPIO_PinInit(XBEE_UART_RESET, &xbee_reset_as_output);
GPIO_PinInit(XBEE_UART_AWAKE, &xbee_awake);
// Init LPUART
CLOCK_SetLpuart0Clock(1U);

// Port A pin 1 DMA Interrupt
PORT_SetPinInterruptConfig(PORTA, 1, kPORT_DMAEitherEdge);

LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = XBEE_UART_BAUD_RATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init(XBEE_UART, &config, XBEE_UART_CLK_FREQ);

DMAMUX_Init(XBEE_UART_DMAMUX_BASEADDR);
DMAMUX_SetSource(XBEE_UART_DMAMUX_BASEADDR, XBEE_UART_TX_DMA_CHANNEL, XBEE_UART_TX_DMA_REQUEST);
DMAMUX_EnableChannel(XBEE_UART_DMAMUX_BASEADDR, XBEE_UART_TX_DMA_CHANNEL);
DMAMUX_SetSource(XBEE_UART_DMAMUX_BASEADDR, XBEE_UART_RX_DMA_CHANNEL, XBEE_UART_RX_DMA_REQUEST);
DMAMUX_EnableChannel(XBEE_UART_DMAMUX_BASEADDR, XBEE_UART_RX_DMA_CHANNEL);

DMA_Init(XBEE_UART_DMA_BASEADDR);
DMA_CreateHandle(&xbee_uart_TxDmaHandle, XBEE_UART_DMA_BASEADDR, XBEE_UART_TX_DMA_CHANNEL);
DMA_CreateHandle(&xbee_uart_RxDmaHandle, XBEE_UART_DMA_BASEADDR, XBEE_UART_RX_DMA_CHANNEL);

LPUART_TransferCreateHandleDMA(XBEE_UART, &xbee_uart_handle, _xbee_lpuart_callback, NULL, &xbee_uart_TxDmaHandle,
&xbee_uart_RxDmaHandle);

XBEE_SET_POWER_ON(true); // Turn Module On
// uint8_t temp[6] = {0};
// XBEE_UART_READ(temp, 6);
}

Callback Func

void _xbee_lpuart_callback(LPUART_Type *base, lpuart_dma_handle_t *handle, status_t status, void *userData)
{
printf("LPUART USER CALLBACK -- STATUS: %d \n", status);
userData = userData;
if (kStatus_LPUART_TxIdle == status)
{
printf("LPUART USER CALLBACK -- TX IDLE \n");
xbee_uart_txOnGoing = false;
}

if (kStatus_LPUART_RxIdle == status)
{
printf("LPUART USER CALLBACK -- RX IDLE \n");
xbee_uart_rxOnGoing = false;
}
if (kStatus_LPUART_RxHardwareOverrun == status)
{
}
}

My TX and RX Functions

void XBEE_UART_WRITE(uint8_t *data, uint32_t length)
{
printf("LPUART SEND BEGIN \n");
xbee_uart_send_xfer.data = data;
xbee_uart_send_xfer.dataSize = length;
xbee_uart_txOnGoing = true;
LPUART_TransferSendDMA(XBEE_UART, &xbee_uart_handle, &xbee_uart_send_xfer);
/* Wait send finished */
while (xbee_uart_txOnGoing)
{
}

printf("Done: ");
for(uint32_t x = 0; x < length; x++)
{
printf("-%X-", *(data+x));
}
printf("\n");
}

void XBEE_UART_READ(uint8_t *data, uint32_t length)
{
printf("LPUART RX BEGIN \n");
xbee_uart_receive_xfer.data = data;
xbee_uart_receive_xfer.dataSize = length;
xbee_uart_rxOnGoing = true;
LPUART_TransferReceiveDMA(XBEE_UART, &xbee_uart_handle, &xbee_uart_receive_xfer);
while (xbee_uart_rxOnGoing)
{
}

printf("Done: ");
for(uint32_t x = 0; x < length; x++)
{
printf("-%X-", *(data+x));
}
printf("\n");
}

And console output:

_xbee_cmd_issue_list: next command ATHV
atcmd header is:
08 01 48 56 ..HV
LPUART SEND BEGIN
LPUART USER CALLBACK -- STATUS: 1302
LPUART USER CALLBACK -- TX IDLE
Done: -7E--0--4-
LPUART SEND BEGIN
LPUART USER CALLBACK -- STATUS: 1302
LPUART USER CALLBACK -- TX IDLE
Done: -8--1--48--56-
LPUART SEND BEGIN
LPUART USER CALLBACK -- STATUS: 1302
LPUART USER CALLBACK -- TX IDLE
Done: -58-
Waiting for driver to query the XBee device...
LPUART RX BEGIN
LPUART USER CALLBACK -- STATUS: 1303
LPUART USER CALLBACK -- RX IDLE
Done: -7E-
LPUART RX BEGIN

So I grab the first byte, then go to grab another and nothing happens (the transfer callback never occurs).

Thank you for your help!

Labels (2)
0 Kudos
1 Reply

406 Views
mjbcswitzerland
Specialist V

Hi Mitchell

If you receive one byte by DMA but no further ones it may be that you are not correctly "reconfiguring" the DMA channel so that it can restart again after the first transfer has terminated.

In case of continued difficulties use the uTasker open source project as reference [https://github.com/uTasker/uTasker-Kinetis] which includes LPUART Tx and Rx DMA support: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
and simulations the KLx7, including LPUART, interrupt and DMA behaviour.

And see Kx7 DMA LPUART videos at
- https://www.youtube.com/watch?v=dNZvvouiqis&list=PLWKlVb_MqDQFZAulrUywU30v869JBYi9Q&index=10
- https://www.youtube.com/watch?v=GaoWE-tMRq4&list=PLWKlVb_MqDQFZAulrUywU30v869JBYi9Q&index=11

In case of professional needs it can also serve as an industrially proven, turn-key solution.

Regards

Mark


Complete KLx7 solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
Kinetis K27:
- http://www.utasker.com/kinetis/FRDM-KL27Z.html
- http://www.utasker.com/kinetis/Capuccino-KL27.html

0 Kudos