Hi,
I have implemented the following code to transmit data over UART channel using eDMA in MPC5675K.
I am not able to get transmitted data through DMA to UART on terminal.
Kindly, suggest anything missed in code.
#define NUMBER_OF_BYTES 16
#define DMA_CHANNEL_MASTER_TRANSMIT 0
const uint8_t TransmitBuffer[NUMBER_OF_BYTES] = {"AAA_BBB_CCC"};
int main(void){
bridges_config ();
init_dma_mux();
init_EDMA_0_tcd();
DP_OBC_0402_DMA_UART_Configure(DP_OBC_BAUD_RATE_115200, 0x45e6);
uart_pad_configuration();
EDMA_0.DMASERQ.R = DMA_CHANNEL_MASTER_TRANSMIT; /* Enable EDMA_0 channel 0 DSPI_1 TX*/
for(;;){
OBC_Printf("Transmitted1\n");
}
}
short DP_OBC_0402_DMA_UART_Configure(const const unsigned long in_usBaudRate, const float in_fClockFreq)
{
volatile struct LINFLEX_tag *SLINFLEX_tag = NULL;
SLINFLEX_tag = &LINFLEX_2;
/* Initiate Initialisation mode*/
SLINFLEX_tag->LINCR1.B.SLEEP = DP_OBC_UART_SET_SLEEP; /* Clear the sleep Mode */
SLINFLEX_tag->LINCR1.B.INIT = DP_OBC_UART_REQ_HW_INIT; /* Request the hardware initialization */
while (0x1000 != (SLINFLEX_tag->LINSR.R & 0xF000)) /* wait for the INIT mode ==> Timeout has to be added */
{
}
/* configure for UART mode */
SLINFLEX_tag->UARTCR.R = 0x0001; /* set the UART bit first to be able to write the other bits */
SLINFLEX_tag->UARTCR.R = 0x0033; /* 8bit data, no parity, Tx and Rx enabled, UART mode */
/* Transmit buffer size = 1 (TDFL = 0 */
/* Receive buffer size = 1 (RDFL = 0) */
LINFLEX_1.DMATXE.R = 0x0000ffff; //enable DMA
//LINFLEX_1.DMARXE.R = 0x000000ff; //enable DMA
LINFLEX_1.UARTCR.B.RFBM = 1;
LINFLEX_1.UARTCR.B.TFBM = 1; /* Transmit FIFO/buffer mode */
/* Compute the nearest integer value */
ulBaudValue = (unsigned long)(in_fClockFreq / (16 * in_usBaudRate));
fIntermedVal = (in_fClockFreq / (16 * in_usBaudRate));
/* Convert the nearest fractional value */
ulFractionValue = (unsigned long)ceil((fmod(fIntermedVal,ulBaudValue) * 16));
if(ulFractionValue > 16)
{
ulFractionValue = 16;
}
SLINFLEX_tag->LINFBRR.R = ulFractionValue;
SLINFLEX_tag->LINIBRR.R = ulBaudValue;
SLINFLEX_tag->LINCR1.B.INIT = DP_OBC_UART_STOP_HW_INIT;
}
}
void uart_pad_configuration()
{
short sRetVal = 0;
unsigned short usLoop = 0;
/* UART pins of the micro-controller */
static const SGPIO_CONFIG SUART[] = {
{OBC_RS422_CH2_TXD_PIN, OBC_RS422_CH2_TXD_ALT_FUNCTION, OBC_RS422_CH2_TXD_INPUT_BUFFER_STATE},
{OBC_RS422_CH2_RXD_PIN, OBC_RS422_CH2_RXD_ALT_FUNCTION, OBC_RS422_CH2_RXD_INPUT_BUFFER_STATE}};
/* UART pins configuration */
for(usLoop =0; usLoop < sizeof(SUART)/sizeof(SUART[0]); usLoop++)
{
sRetVal = DP_OBC_0402_GPIO_config_mux_pins(SUART[usLoop].usPinNo, SUART[usLoop].ucAltFn, SUART[usLoop].ucAdditionalIN);
}
SIU.PSMI[49].B.PADSEL = 0x01; /* Configure PSMI Reg 49 to select GPIO[60] as UART2 Rx Line */
SIU.GPDO[113].B.PDO = 0x01; /* Flash WP, Should be high to enable write and erase operation */
}
short DP_OBC_0402_GPIO_config_mux_pins(const unsigned long in_ulPinNO, unsigned char in_ucAltFunction, unsigned char in_ucAdditionalINEnable)
{
/* Update the alternate function */
SIU_tag_Obj.PCR[in_ulPinNO].B.PA = in_ucAltFunction;
/* Update the additional INPUT enable --> which means the update the input buffer enable */
if(in_ucAdditionalINEnable)
{
SIU_tag_Obj.PCR[in_ulPinNO].B.IBE = in_ucAdditionalINEnable;
}
/* Update the values to the register */
SIU.PCR[in_ulPinNO].R = SIU_tag_Obj.PCR[in_ulPinNO].R;
}
void init_dma_mux()
{
DMAMUX_0.CHCONFIG[0].R = 0xA3; /* DMA Chan 0 enables LINFlexD_2 TX (src 35) */
//DMAMUX_0.CHCONFIG[0].R = 0x99; /* DMA Chan 0 enables LINFlexD_1 RX (src 23) */
}
void bridges_config (void)
{
PBRIDGE_0.MPROT0_7.B.MPROT2_MTW = 1; /* This master is trusted for write accesses */
PBRIDGE_0.MPROT0_7.B.MPROT2_MTR = 1; /* This master is trusted for read accesses */
PBRIDGE_0.MPROT0_7.B.MPROT2_MPL = 1; /* Accesses from this master are not forced to user-mode */
PBRIDGE_0.PACR16_23.B.PACR17_SP = 0; /*Supervisor Protect (PACR--> 17 for eDMA)*/
PBRIDGE_0.OPACR48_55.B.OPACR50_SP = 0; /*Off-platform peripheral access control for LINFlexD_1 (OPACR no-->49 for LINFlexD_1)*/
PBRIDGE_0.OPACR16_23.B.OPACR23_SP = 0; /*Off-platform peripheral access control for DMA_MUX (OPACR no-->23 for DMA_MUX)*/
/* Refer MPC5675K Microcontroller datasheet for more info */
}
void init_EDMA_0_tcd()
{
/*** source settings ***/
EDMA_0.DMAERQL.R = 0x0;
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].SADDR = (vuint32_t) &TransmitBuffer; // source address - command_word
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].SSIZE = 0; /* Read 2**0 = 1 byte per transfer */
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].SOFF = 1; // addr increment after transfer in bytes
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].SLAST = 0; // after major loop, do not change
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].SMOD = 0; // source modulo feature not used
/*** destination settings ***/
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DADDR = ((vuint32_t)&LINFLEX_2.BDRL.R); // dest. address - command PUSH register
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DSIZE = 0; // 32-bit
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DOFF = 1; // no addr increment after transfer
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DLAST_SGA = 0; // after major loop, do not change addr
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DMOD = 0; /* 0/1 Interrupt disabled/enabled*/ // destination modulo feature not used
/*** counts ***/
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].D_REQ = 1; // do not disable channel when major loop is done
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].NBYTES = 1; // 4 bytes per minor loop
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].BITER = NUMBER_OF_BYTES; // major iteration count - lenght of message
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].CITER = NUMBER_OF_BYTES; // major iteration count - lenght of message
/*** linking ***/
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].CITERE_LINK = 0; // disabled
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].BITERE_LINK = 0; // disabled
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].MAJORE_LINK = 0; // disabled
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].MAJORLINKCH = 0; // disabled
/*** others ***/
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].INT_HALF = 0; // interrupt is not used
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].INT_MAJ = 0; // interrupt is not used
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].E_SG = 0; // disable scatter/gather operation
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].BWC = 0; // default bandwidth control- no stalls
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].START = 0;
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DONE = 0;
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].ACTIVE = 0;
}
已解决! 转到解答。
You have incorrect destination address and destination offset
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DADDR = ((vuint32_t)&LINFLEX_2.BDRL.R) + 3;
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DOFF = 0; // no addr increment after transfer
You have incorrect destination address and destination offset
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DADDR = ((vuint32_t)&LINFLEX_2.BDRL.R) + 3;
EDMA_0.TCD[DMA_CHANNEL_MASTER_TRANSMIT].DOFF = 0; // no addr increment after transfer