Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 251352

Forum Post: RM48 FreeRTOS, taskDelay() SCI DMA problem

$
0
0

Hello,


I have the Hercules USB development board running Halcogen generated code based on the 950ZWT FreeRTOS example. I am using version 3.06 of Halcogen and 5.3.0 of Code Composer Studio.

I have two tasks, a Blinky Task which toggles an LED and an SCI Transmission task which outputs messages which I view on the Code Composer Studio Terminal. The Blinky Task sends messages to the SCI Transmission task to be printed via an sci_printf call (which does simple printf style formatting and sends the message via a FreeRTOS message queue to the SCI Transmission task). Everything works fine, until the taskDelay() function executes in the Blinky Task, after it executes, although a message is sent to the SCI Transmission task, and the task attempts to send the message out, the message does not go out. It's as if the DMA transfer completely fails.

If I set the taskDelay to 1, for 1 clock tick, instead of 3000, for 3 seconds. Everything works and all the messages are correctly sent via DMA transfer to the SCI. I am confused.

Here is the Blinky Task:

static portTASK_FUNCTION( BlinkyTask, pvParameters )
{
    const portTickType delay = 3000/portTICK_RATE_MS;    // 3 second delay?
    portTickType lastTickCount;

    sci_printf("Blinky task up and running\r\n");

    SET_LED(LED_MIDDLE_TOP);
    while(1)
    {
        lastTickCount = xTaskGetTickCount();

        sci_printf("Blinky Task ... before task delay, tick count is %d\r\n", lastTickCount);

        vTaskDelay(1);

        sci_printf("Blinky Task ... after task delay\r\n");
        TOGGLE_LED(LED_MIDDLE_TOP);
        sci_printf("Blinky Task ... toggled led\r\n");
    }
}

Here is code to set up the DMA Control Packet.

void dmaConfigTxCtrlPacket( uint32 sourceAddress,
                            uint32 destinationAddress,
                            uint32    length) {
    dmaTxCtrlPacket.SADD = sourceAddress;            // RAM address
    dmaTxCtrlPacket.DADD = destinationAddress;        // peripheral address
    dmaTxCtrlPacket.CHCTRL = 0;                        // channel control
    dmaTxCtrlPacket.FRCNT = length;                    // source address length
    dmaTxCtrlPacket.ELCNT = 1;                        // 1 byte
    dmaTxCtrlPacket.ELDOFFSET = 0;                    // element destination offset
    dmaTxCtrlPacket.ELSOFFSET = 0;                    // element source offset
    dmaTxCtrlPacket.FRDOFFSET = 0;                    // frame destination offset
    dmaTxCtrlPacket.FRSOFFSET = 0;                    // frame source offset
    dmaTxCtrlPacket.PORTASGN = 4;                    // port b
    dmaTxCtrlPacket.RDSIZE = ACCESS_8_BIT;            // read element size
    dmaTxCtrlPacket.WRSIZE = ACCESS_8_BIT;            // write element size
    dmaTxCtrlPacket.TTYPE = FRAME_TRANSFER;            // transfer type: frame
    dmaTxCtrlPacket.ADDMODERD = ADDR_INC1;            // read address mode: post increment
    dmaTxCtrlPacket.ADDMODEWR = ADDR_FIXED;            // write address mode: fixed
    dmaTxCtrlPacket.COMBO = AUTOINIT_OFF;            // autoinit off

}

And here is the code to send the message via DMA. Note that I added the FTC interrupt enable to see if I got an FTC interrupt on the first message that fails, I didn't. And note that those first lines of code were executed before the task was started and the behavior was the same. I put the code here to see if maybe the DMA set up was corrupted, but the behavior is the same:


static void sciDMASend(int length, uint8 *data)
{
      dmaEnable();
     dmaEnableInterrupt(DMA_CH0, BTC);    // enable interrupt after receipt of data
     dmaEnableInterrupt(DMA_CH0, FTC);
     dmaReqAssign(DMA_CH0, 29);

    dmaConfigTxCtrlPacket(                    // First transmission control packet
                (uint32)(data),                // source address is message
                (uint32)(&scilinREG->TD),    // destination address transmit buffer of SCI LIN
                length);                    // number of byte to transmit
    dmaSetCtrlPacket(DMA_CH0, dmaTxCtrlPacket);
    dmaSetChEnable(DMA_CH0, DMA_HW);        // set dma chan 0 to trigger on h/w request

    scilinREG->SETINT = (1 << 16);            // enable TX DMA
}

Any ideas or suggestions would be great. Thank you.

Ruth


Viewing all articles
Browse latest Browse all 251352

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>