This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LS3137: SCI DMA not working

Other Parts Discussed in Thread: TMS570LS3137

Hello guys, 

I'd been following some other problems on SCI2 based DMA transfers which are answered, but even following the instructions and considering the available solutions, I still could not make my code below to work. The individual byte sent over SCI works fine but DMA does not transmit. I would appreciate anyone who can provide me with some idea how I can make it work and if I am doing something wrong.

Regards

Sohal.

// global for this example
uint8_t datagramToSend[7];

// send data every 200 µs via SCI component of TMS570LS3137
main(){
m_datagramToSend.header = 0xaa;
m_datagramToSend.payload = 0xaaaaaaaa;
m_datagramToSend.crc = 0xaaaa;
sciInit();
dmaInit();

// 5 kHz loop
while(true) {
wait();
dmaSetChEnable(DMA_CH0, DMA_HW);
}
}

/**
* Configure DMA channels for transmission and reception of datagrams.
*/
void SerialPumpPort::dmaInit(){

// TX line, DMA configuration for transmission via SCI bus
dmaReqAssign(DMA_CH0, 31); // assign request line 31 to channel 0
dmaEnableInterrupt(DMA_CH0, BTC); // enable interrupt for block transfer complete
// setting DMA control packets for transmit
g_dmaCTRL dma_control_TX;
dma_control_TX.SADD = (uint32) &datagramToSend; // initial source address
dma_control_TX.CHCTRL = 0; // is overwritten by some of the next commands
dma_control_TX.DADD = (uint32) 0xFFF7E538; // initial destination address
dma_control_TX.FRCNT = 7U; // frame count (ITCOUNT)
dma_control_TX.ELCNT = 1U; // element count (ITCOUNT)
dma_control_TX.ELDOFFSET = 0U; // element destination offset
dma_control_TX.ELSOFFSET = 0U; // element source offset
dma_control_TX.FRDOFFSET = 0U; // frame detination offset
dma_control_TX.FRSOFFSET = 0U; // frame source offset
dma_control_TX.PORTASGN = 4U; // channel 0 assigned to port B (PAR0)
dma_control_TX.RDSIZE = ACCESS_8_BIT; // read element size
dma_control_TX.WRSIZE = ACCESS_8_BIT; // write element size
dma_control_TX.TTYPE = FRAME_TRANSFER; // trigger type - frame/block
dma_control_TX.ADDMODERD = ADDR_INC1; // addresssing mode for source
dma_control_TX.ADDMODEWR = ADDR_FIXED; // addresssing mode for destination
dma_control_TX.AUTOINIT = AUTOINIT_OFF; // auto-init mode
dmaSetCtrlPacket(DMA_CH0, dma_control_TX);
// enable DMA
dmaEnable();
}

/**
* This function initializes the SCI module.
*/
void sciInit(void)
{
/* USER CODE BEGIN (2) */
/* USER CODE END */

/** @b initialize @b SCI */

/** - bring SCI out of reset */
sciREG->GCR0 = 0U;
sciREG->GCR0 = 1U;

/** - Disable all interrupts */
sciREG->CLEARINT = 0xFFFFFFFFU;
sciREG->CLEARINTLVL = 0xFFFFFFFFU;

/** - global control 1 */
sciREG->GCR1 = (uint32)((uint32)1U << 25U) /* enable transmit */
| (uint32)((uint32)1U << 24U) /* enable receive */
| (uint32)((uint32)1U << 5U) /* internal clock (device has no clock pin) */
| (uint32)((uint32)(1U-1U) << 4U) /* number of stop bits */
| (uint32)((uint32)0U << 3U) /* even parity, otherwise odd */
| (uint32)((uint32)0U << 2U) /* enable parity */
| (uint32)((uint32)1U << 1U); /* asynchronous timing mode */

/** - set baudrate */
sciREG->BRS = 3U; /* baudrate */

/** - transmission length */
sciREG->FORMAT = 8U - 1U; /* length */

/** - set SCI pins functional mode */
sciREG->PIO0 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */

/** - set SCI pins default output value */
sciREG->PIO3 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */

/** - set SCI pins output direction */
sciREG->PIO1 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */

/** - set SCI pins open drain enable */
sciREG->PIO6 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */

/** - set SCI pins pullup/pulldown enable */
sciREG->PIO7 = (uint32)((uint32)0U << 2U) /* tx pin */
| (uint32)((uint32)0U << 1U); /* rx pin */

/** - set SCI pins pullup/pulldown select */
sciREG->PIO8 = (uint32)((uint32)1U << 2U) /* tx pin */
| (uint32)((uint32)1U << 1U); /* rx pin */

/** - set interrupt level */
sciREG->SETINTLVL = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)0U << 9U) /* Receive */
| (uint32)((uint32)0U << 8U) /* Transmit */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U << 0U); /* Break detect */

/** - set interrupt enable */
sciREG->SETINT = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)1U << 9U) /* Receive */
| (uint32)((uint32)0U << 1U) /* Wakeup */
| (uint32)((uint32)0U << 0U); /* Break detect */

// added!!
sciREG->SETINT |= (1 << 18); // set interrupt for RX DMA ALL
sciREG->SETINT |= (1 << 17); // set interrupt for RX DMA
sciREG->SETINT |= (1 << 16); // set interrupt for TX DMA

/** - initialize global transfer variables */
g_sciTransfer_t[0U].mode = (uint32)1U << 8U;
g_sciTransfer_t[0U].tx_length = 0U;
g_sciTransfer_t[0U].rx_length = 0U;

/** - Finaly start SCI */
sciREG->GCR1 |= 0x80U;
}

  • Sohal,

    It's pretty hard to spot an error w. just the source code (for me anyway).

    Here's how I would debug.

    1) I'd probably comment out or skip over dmaSetChEnable(DMA_CH0, DMA_HW); when executing, just so that the DMA doesn't respond before I can inspect the chain of events from SPI to DMA.

    2) I'd run the code to the point where you believe the SCI should have triggered the DMA request.

    3) I'd start checking the status bits. Either forward from the SCI or backward.
    For example, if you check the PEND register of the DMA you can see whether or not the DMA got the request from the SCI.
    If it did, then you focus on things inside the DMA controller. For example is the control packet actually configured correctly, and are there any configuration issues in the DMA registers.
    If it didn't get the request at the DMA controller PEND reigster, then you focus on the SCI - why didn't the SCI make the request. ... What do the SCI status registers tell you.

    Most likely it's just one step left out in the sequence above but it's a lot easier to find this by inspecting the hardware state than the code.

    Give this a shot. If it doesn't work for you then maybe you can upload your project so we can run it and do the above here.
  • Sohal,

    I've noticed in your control packet definition the following:

    dma_control_TX.DADD = (uint32) 0xFFF7E538; // initial destination address

    dma_control_TX.RDSIZE = ACCESS_8_BIT; // read element size

    TMS570ls3137 is a big endian part.

    The destination address you are using is a 32 bit address. Using element size = 8Bits means the DMA will do a bit access to 0xFFF7E538
    This is not correct. For 8bits access the destination address should be: 0xFFF7E53B

    Please havea try and let me know.

  • Thanks for your reply. Its now fully functional. The endian-ness is the culprit here. Thanks a lot from my colleague and Merry Christmas.