AnsweredAssumed Answered

DMA buffer to Tx UART on K10DN512

Question asked by Gerrie Heath on Apr 25, 2019
Latest reply on Apr 25, 2019 by Mark Butcher

I am using a K10DN512VLQ10 chip in the older Kinetis Design Studio V3.2.0. I am not using any libraries and the drivers are self developed. 

 

I want to start using the DMA controller to transmit variable length messages over UART2. I have tried everything and cannot get it to work. It is either a case of only the first cycle of the minor loop is execute and stops there, or all data is dumped immediately to the UART thereby overrunning it. 

Only the first character of the buffer is seen on the UART. The DMA done bit is set.

 

To test I have written this code. The transfer is software triggered and transmits 8 bytes from a 'str' buffer (type char str[]). Only 1 major loop and no linkage.  

 

UART2_BASE_PTR->C2 = 0;


// Enable clock for DMAMUX and DMA
SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;

//disable request channels
DMA0->ERQ = 0u;
DMA0->EEI = 0u;
DMA0->SEEI = 0u;

// Clear pending errors and/or the done bit
DMA0->ES = 0u;

//set source addr
DMA0->TCD[0].SADDR = (__IO uint32_t)str;
DMA0->TCD[0].NBYTES_MLNO = 8;
DMA0->TCD[0].ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0); //8-bit transfer
DMA0->TCD[0].DADDR = (__IO uint32_t)&UART2_BASE_PTR->D;
DMA0->TCD[0].CSR = DMA_CSR_BWC(3) | DMA_CSR_DREQ_MASK

// Adjustment value used to restore the source and destiny address to the initial value
DMA0->TCD[0].SLAST = 0;//(-1 * size_of_tx); // Source address adjustment
DMA0->TCD[0].DLAST_SGA = 0;//(-1); // Destination address adjustment
// Set an offset for source and destination address
DMA0->TCD[0].SOFF = 0x00; // Source address offset
DMA0->TCD[0].DOFF = 0x00; // Destination address

// Current major iteration count (a single iteration of 'size_of_tx' bytes)
DMA0->TCD[0].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(1);
DMA0->TCD[0].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(1);

 

UART_C1_REG(m_uart) = UART_C1_UARTSWAI_MASK | UART_C1_ILT_MASK;

UART_PFIFO_REG(m_uart) = 0u;
UART_TWFIFO_REG(m_uart) = 0u;

SetSpeed(baud);   //sets baud

UART2_BASE_PTR->C2 = UART_C2_TIE_MASK;
UART2_BASE_PTR->C5 = UART_C5_TDMAS_MASK;

SetIrqStatus(irq, priority);
m_configured = true;
uint8_t temp_val = UART2_BASE_PTR->S1;
UART2_BASE_PTR->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK);


DMA0->CERR = DMA_CERR_CAEI_MASK;
DMA0->CERQ = DMA_CERQ_CAER_MASK;

 

// Enable request signal for channel 0
DMAMUX->CHCFG[0] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(7);    //UART2 TX


DMA0->ERQ = 1;
DMA0->TCD[0].CSR |= DMA_CSR_START_MASK;

 

//wait for DMA to complete

while(!(DMA0->TCD[0].CSR & DMA_CSR_DONE_MASK)); //DMA_CSR_DREQ_MASK

Outcomes