Part Number: TM4C1294NCPDT
Hello Team,
I'm Working on DMA Transfer to UART Peripheral in TM4C1294NCPDT(Customised Board). Facing issue while sending bytes from Pkt2(Array of size 312 bytes) to another Controller. But the Problem is DMA transfer function is not working as expected it is sending random bytes compared to actual bytes.
1) I'm Filling an Array in one Function to Transmit those bytes to another controller.
2) After Filling 312 bytes in an Array(Pkt2 named in Program), I'm Using " MAP_uDMAChannelEnable(UDMA_CH17_UART3TX);" to initiate DMA Transfer.
3) Where it is going wrong i was unable to recognise. Can Someone help me how DMA is working in this scenario and Help me to resolve this issue.
I want to send 312 data bytes from internal Array(Pkt2) to Another Micro-Controller without any data loss using DMA_Tx.
Attaching configuration for both DMA Rx and Tx and Also Output i got. Any help would be very thankful.
void Init_UART3()
{
//
// Enable the GPIO Peripheral used by the UART.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable UART3.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
//
// Enable processor interrupts.
//
IntMasterEnable();
//
// Configure GPIO Pins for UART mode.
//
GPIOPinConfigure(GPIO_PA4_U3RX);
GPIOPinConfigure(GPIO_PA5_U3TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//
// Initialize the UART for console I/O.
//
MAP_UARTConfigSetExpClk(UART3_BASE, gu32SysClk, 230400,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_RXE;
HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_TXE;
// HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_LBE;
// Make sure there is no junk left in the FIFO
while (UARTCharGetNonBlocking(UART3_BASE) != -1);
MAP_UARTFIFOEnable(UART3_BASE);
MAP_UARTFIFOLevelSet(UART3_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
// Make sure there is no junk left in the FIFO
while (UARTCharGetNonBlocking(UART3_BASE) != -1);
}
void Init_UART3_DMA(void)
{
MAP_uDMAChannelAssign(UDMA_CH16_UART3RX);
MAP_uDMAChannelAssign(UDMA_CH17_UART3TX);
//
// Enable the UART for operation, and enable the uDMA interface for both TX
// and RX channels.
//
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_RX);
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_TX);
//
// Put the attributes in a known state for the uDMA UART1RX channel. These
// should already be disabled by default.
//
MAP_uDMAChannelAttributeDisable(UDMA_CH16_UART3RX,
UDMA_PRI_SELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
//
// Configure the control parameters for the primary control structure for
// the UART RX channel. The primary contol structure is used for the "A"
// part of the ping-pong receive. The transfer data size is 8 bits, the
// source address does not increment since it will be reading from a
// register. The destination address increment is byte 8-bit bytes. The
// arbitration size is set to 4 to match the RX FIFO trigger threshold.
// The uDMA controller will use a 4 byte burst transfer if possible. This
// will be somewhat more effecient that single byte transfers.
//
MAP_uDMAChannelControlSet(UDMA_CH16_UART3RX | UDMA_PRI_SELECT,
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_2);
MAP_uDMAChannelTransferSet(
UDMA_CH16_UART3RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void*) (UART3_BASE + UART_O_DR), gu16Array,
sizeof(gu16Array) >> 1u);
MAP_uDMAChannelAttributeEnable(UDMA_CH16_UART3RX,
UDMA_PRI_SELECT | UDMA_ATTR_USEBURST);
/* Tx DMA setting */
/* clear any previous defined attribute */
uDMAChannelAttributeDisable(UDMA_CH17_UART3TX , UDMA_PRI_SELECT
| UDMA_ATTR_USEBURST |
UDMA_ATTR_REQMASK);
MAP_uDMAChannelAttributeEnable(UDMA_CH17_UART3TX, UDMA_ATTR_USEBURST);// UDMA_PRI_SELECT
/* set the control pars */
uDMAChannelControlSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT , UDMA_SIZE_16 |
UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2);
uDMAChannelTransferSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
Pkt2, (void *)(UART3_BASE + UART_O_DR),
312);
/////////////////////////////////////////////////
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_RX);
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_TX);
MAP_uDMAChannelEnable(UDMA_CH16_UART3RX);
//
// Enable the UART DMA TX/RX interrupts.
//
MAP_UARTIntEnable(UART3_BASE, UART_INT_DMARX | UART_INT_DMATX);
MAP_UARTEnable(UART3_BASE);
//
// Enable the UART interrupt.
//
MAP_UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT); //UART_INT_RX |
}
uint16_t Pkt2[312];
int main()
{
Init_SysClk();
Init_GPIO();
Init_UART3();
Init_UART3_DMA();
//uint8_t lu8Index;
uint8_t lu8Checksum;
uint8_t inc = 0;
uint16_t lu16PktIndex = 0;
while(1)
{
// Preparing 312 bytes in Pkt2 Array
for (i = 0; i < 52; i++)
{
Pkt2[lu16PktIndex] = gu8Command2;
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = gu8Data2 + inc;
inc++;
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
OnTime1 = gu16SineArray[0][i]; //One ON Long Time
OffTime1 = gu16SineArray[1][i];
Pkt2[lu16PktIndex] = (OnTime1 & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = ((OnTime1 >> 7) & 0x03);
Pkt2[lu16PktIndex] = Pkt2[lu16PktIndex] | ((OffTime1 << 2) & 0x7F);
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = ((OffTime1 >> 5) & 0x0F);
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] | ((Mode << 5) & 0x60));
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
lu8Checksum = lu8Checksum & 0x7F;
Pkt2[lu16PktIndex++] = lu8Checksum;
lu16PktIndex &= 0x01FF;
}
// After i = 52 initiating DAM transfer
if (i >= 52)
{
MAP_uDMAChannelEnable(UDMA_CH17_UART3TX);
}
}
}
Below is the DMA transferred Data which is very random/ Not Expected Data to transfer.