Issue with k20 EDMA DREQ bit

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

Issue with k20 EDMA DREQ bit

796 Views
murugesan_dinak
Contributor II

Using two UART channel. Each channel is configured with EDMA for transmission. 

Both UART channels are transmitting data simultaneously. 

The problem is getting data bytes of previously sent bytes.

It seems like EDMA is retransmitting data bytes which was already transmitted in the previous call.

This is observed when we run multiple ports at same time at high baud rate.

config:

SADDR = data_buff[];
DADDR = UART data register
NBYTES_MLOFFNO = 1
minor loop linking disabled and SCG mode disabled
CITER_ELINKNO = bytes_to_be_transmit
BITER_ELINKNO = bytes_to_be_transmit
SOFF = 1
DOFF = 0
ATTR_SSIZE = 8bit
ATTR_DSIZE = 8bit
SLAST =0
DLAST_SGA = 0
CSR_DREQ =1
CSR_INTMAJOR =1

Note: Using fixed priority arbitration. 

And the transfer starts after setting ERQ bit of particular channel.  

0 Kudos
4 Replies

705 Views
murugesan_dinak
Contributor II

Thank you jing for your valuable reply.

I have fixed this issue by disabling EDMA channel from DMUX after done interrupt and  enabling again before setting ERQ bit.

Thanks and Regards

Dinakaran

0 Kudos

705 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

Can you give example code for the problem? Or, k20 has SDK package. There is EDMA example and UART-DMA examples. You can refer to it.

Regards,

Jing

0 Kudos

705 Views
murugesan_dinak
Contributor II

void hal_serial_k20_uart_edma_config_tx(hal_serial_channel_t port_id)
{
hal_serial_k20_uart_port_t *port;
port = (hal_serial_k20_uart_port_t *)hal_serial_port_list[port_id];

/*Configuring DMA channel for data transfer*/
port->k20_uart_edma_channel = port->port_cfg->td_port_config.k20_uart_edma_tx_chn;

/*Configure the destination address as the K20_UART data register as the data needs to be moved from the local buffer to K20_UART DATA buffer*/
R_EDMA_DMA_DADDR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = port->port_cfg->td_port_config.k20_uart_data_reg_addr;
/*Configure the source address as the data array*/
R_EDMA_DMA_SADDR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) =(hal_u32_t)(&port->k20_uart_edma_tx_buf[0]);

/*Update the no of bytes to be transmitted in one single interrupt*/
R_EDMA_DMA_NBYTES_MLOFFNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = 1;

/*Disable the minor loop source and destination offset*/
R_EDMA_DMA_NBYTES_MLOFFNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_NBYTES_MLOFFNO_SMLOE << R_SO_EDMA_DMA_NBYTES_MLOFFNO_SMLOE);
R_EDMA_DMA_NBYTES_MLOFFNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_NBYTES_MLOFFNO_DMLOE << R_SO_EDMA_DMA_NBYTES_MLOFFNO_DMLOE);

/*Disable the channel-channel linking on completion of minor loop*/
R_EDMA_DMA_CITER_ELINKNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_CITER_ELINKNO_ELINK << R_SO_EDMA_DMA_CITER_ELINKNO_ELINK);
R_EDMA_DMA_BITER_ELINKNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_BITER_ELINKNO_ELINK << R_SO_EDMA_DMA_BITER_ELINKNO_ELINK);

/*Set the CITER count as the no of bytes to be transmitted*/
R_EDMA_DMA_CITER_ELINKNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = port->bytes_to_be_transmit;
R_EDMA_DMA_BITER_ELINKNO(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = port->bytes_to_be_transmit;

/*Set the source offset as 1 as the array index needs to be incremented while reading from the local buffer*/
R_EDMA_DMA_SOFF(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = 1;
R_EDMA_DMA_DOFF(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = 0;

/*Set the source address and destination address data size*/
R_EDMA_DMA_ATTR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_ATTR_SSIZE << R_SO_EDMA_DMA_ATTR_SSIZE);
R_EDMA_DMA_ATTR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_ATTR_DSIZE << R_SO_EDMA_DMA_ATTR_DSIZE);

/*Disable the address modulo feature*/
R_EDMA_DMA_ATTR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_ATTR_DMOD << R_SO_EDMA_DMA_ATTR_DMOD);
R_EDMA_DMA_ATTR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_ATTR_SMOD << R_SO_EDMA_DMA_ATTR_SMOD);

/*Disable the bandwidth control*/
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_CSR_BWC << R_SO_EDMA_DMA_CSR_BWC);

/*Disable the channel to channel linking on major loop complete */
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_CSR_MAJORLINKCH << R_SO_EDMA_DMA_CSR_MAJORLINKCH);

/*Disbale the major loop half counter interrupt*/
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_CSR_INTHALF << R_SO_EDMA_DMA_CSR_INTHALF);

/*Initiate interrupt when major loop count completes*/
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) |= (R_M_EDMA_DMA_CSR_INTMAJOR << R_SO_EDMA_DMA_CSR_INTMAJOR);

/*Disable scatter gather mode*/
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_CSR_ESG << R_SO_EDMA_DMA_CSR_ESG);

/* After message is transferred adjust the src address to the beginning */
R_EDMA_DMA_SLAST(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = -port->bytes_to_be_transmit;

/* DLAST_SGA remains the same as data reg address never changes */
R_EDMA_DMA_DLAST_SGA(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) = 0;

/*Enable the DREQ bit so that the ERQ is automatically cleared when the major loop count expires*/
R_EDMA_DMA_CSR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) |= (R_M_EDMA_DMA_CSR_DREQ << R_SO_EDMA_DMA_CSR_DREQ);
/*Enable the request signal for EDMA channel for data transfer*/
R_EDMA_DMA_ERQ(R_O_EDMA) |= 1<<(port->k20_uart_edma_channel) ;

}

This function is continuously called, whenever there is data to transmit.

Each time transmitting sequence of 101 bytes and receiving those bytes in the other end.

Each sequence is packed with sequence number(first 4 bytes) and file separator(last byte 28)

The captured data is as follows

0, 0, 73, 148, 167, 177, 139, 33, 57, 3, 204, 213, 4, 174, 178, 8, 171, 244, 64, 35, 125, 116, 223, 134, 59, 103, 83, 114, 111, 12,
182, 205, 223, 70, 171, 135, 119, 182, 41, 176, 58, 117, 134, 62, 36, 185, 197, 207, 174, 6, 115, 171, 249, 210, 178, 53, 59, 6, 167, 42,
18, 221, 119, 241, 36, 163, 249, 155, 90, 162, 204, 148, 24, 210, 82, 60, 140, 24, 139, 187, 157, 126, 230, 151, 82, 153, 205, 13, 160, 244, 182, 50, 211, 47, 164, 119, 197, 212, 167, 165, 28,
0, 0, 73, 148, 167, 177, 139, 33, 57, 3, 204, 213, 4, 174, 178, 8, --------This is the corrupted message byte. 
0, 0, 73, 149, 65, 223, 66, 89, 178, 148, 21, 191, 45, 32, 250, 202, 31, 225, 99, 113, 251, 176, 253, 27, 30, 37, 180, 78, 248, 227,
242, 240, 54, 17, 132, 227, 209, 227, 38, 170, 22, 58, 63, 85, 230, 96, 80, 178, 254, 178, 149, 112, 46, 197, 237, 74, 234, 162, 24, 100,
7, 12, 85, 61, 156, 89, 33, 111, 188, 198, 26, 210, 2, 90, 41, 104, 58, 248, 154, 57, 43, 48, 41, 89, 117, 23, 35, 97, 57, 60,
69, 191, 199, 26, 253, 100, 242, 152, 191, 155, 44, 28,

This corrupted message byte looks like previous sequence bytes. Got this message in between two valid sequences

How to avoid this behavior.  

0 Kudos

705 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

I've compared your TCD setting with the demo in SDK. It seems there is no problem.

I have 2 concern. First is some definition.  For example:

R_EDMA_DMA_ATTR(R_O_EDMA,port->port_cfg->td_port_config.k20_uart_edma_tx_chn) &= ~(R_M_EDMA_DMA_ATTR_DMOD << R_SO_EDMA_DMA_ATTR_DMOD);

DMOD is a 5bit field. R_M_EDMA_DMA_ATTR_DMOD should be 0x1f. There are many other field like this you should take care.

Second is in some K20 chip, like MK20FX512xxx12 or MK20FN1M0xxx12, UART0 and UART1 peripheral requests trigger DMA twice if core clock and internal bus clock frequencies are equal.

If the problem is still there, you can send me your code.

Regards,

Jing

0 Kudos