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.

CCS: TMS570LS3137 - Sci with DMA : act slave receive/trasmit

Other Parts Discussed in Thread: TMS570LS3137, HALCOGEN

Tool/software: Code Composer Studio

I use TMS570LS3137 ic. I want to use this chip sci communication with DMA as slave. The DMA source code is based on the link ( https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/807027?tisearch=e2e-sitesearch&keymatch=tms570lc3137%2520sci%2520with%2520dma )

The system action

1. SCI communication action

 - Rx(receive) always on and connected with Tx(transmit) line : So when the Tx data send, Rx data get.

 - Tx(transmit) act is controlled by gpio. When bit is set, tx act.

2. Commucation setting(example)

 - Sending data size : 20 bytes

 - Preiod : 20ms

 - After receiving the data, Chip send response same size data to master. 

- Dma Test setting -

1. DMA setting receive and transmit - DMA_CH0 as Tx, DMA_CH1 as Rx (It follow the link source code)

2. Enable the interrupt (BTC) with halcogen, and Set Enable interrupt when receving. - dmaEnableInterrupt(DMA_CH1, BTC);

3. In the interrupt, there are two actions,

    (1) Data correct - when the dma is started with sci communication start

        1) dmadisable

        2) DmaReset : dmaREG->GCTRL = 1U;

        3) Resetting DMA Tx

        4) SCI Tx on

        5) somedelay

        6) DMAenable

        7) wait tx finish : while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);

        8) dmaDisable

        9) some delay - because communication is more slower than MCU

        10) SCI Tx off

        11) DmaReset : dmaREG->GCTRL = 1U;

        12) Setting DMA Rx

        13) DMA enable

 

    (2) Data fail - when the dma is started while sci communication

        1) DMAdisable

        2) wait some delay

        3) DMAReset : dmaREG->GCTRL = 1U; (Because i don't know where the dma point is located.)

        4) Setting DMA Rx

        5) DMAenable


Then, I just want to dma with No reset and Re setting. (In fail case, there is no way to act without DMA reset, but in tx action - I think it is possible action without DMA Reset)

I test sci act without DMA Reset in "Data correct" as followes

  (1) Data correct - when the dma is started with sci communication start

        1) dmadisable

        2) SCI Rx DMA interrupt diasble

        3) SCI Tx on

        4) some delay

        5) DMAenable

        6) wait tx finish : while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);

        7) dmaDisable

        8) some delay - because communication is more slower than MCU

        9) SCI Tx off

        11) SCI Rx DMA interrupt diasble

        12) DMA enable

Then, firmware is stopped in 5) - while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);

I think Rx dma is act when TX dma transmittion. Would you guide me how i can solve this problem?

  • Hello Minwoo,

    I am sorry I am not very clear about your settings. Can you please upload your CCS project?

  • test_code.zip

    Hello QJ Wang,

    I cannot upload CCS project because there the other functions are used in our company. So, I just upload about DMA actions related in previous question.

    Actions as followes,

    1. In main setting "sci_receive_with_dma_init()" funcion is used (in notification.c)

    2. dmaBTCAInterrupt is occurred when sci communication finish. (in sys_dma.c)

    3. dmaGroupANotification is started <- in this function include the action in previous quesiton(in notification.c)

      - here are two case actions.  

       (1) sci start in correct timing (in "if" state)

       (2) sci start in incorrect timing (in "else" state)

    Regards,

    Minwoo

  • Hello Minwoo,

    I will check for you.

  • Hello QJ Wang,

    I test more SCI with DMA.

    First, I set DMA as followes, (just run receive)

        uint32 sciTxData, sciRxData;
        int i;
        g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;

        /*Initialize SCI*/
        sciInit();

        /*Assign DMA request SCI transmit to Channel 0*/
        dmaReqAssign(DMA_CH0, 31);

        /*Assign DMA request SCI receive to Channel 1*/
        dmaReqAssign(DMA_CH1, 30);

        sciTxData = ((uint32_t)(&(sciREG->TD)) + 3);
        sciRxData = ((uint32_t)(&(sciREG->RD)) + 3);

        /*Configure control packet for Channel 0*/
        g_dmaCTRLPKT1.SADD      = (uint32_t)TX_DATA;    /* source address             */
        g_dmaCTRLPKT1.DADD      = sciTxData;            /* destination  address       */
        g_dmaCTRLPKT1.CHCTRL    = 0;                    /* channel control            */
        g_dmaCTRLPKT1.FRCNT    = PROTOCOL_SIZE;                  /* frame count                */
        g_dmaCTRLPKT1.ELCNT     = 1;                    /* element count              */
        g_dmaCTRLPKT1.ELDOFFSET = 0;                    /* element destination offset */
        g_dmaCTRLPKT1.ELSOFFSET = 0;                    /* element destination offset */
        g_dmaCTRLPKT1.FRDOFFSET = 0;                    /* frame destination offset   */
        g_dmaCTRLPKT1.FRSOFFSET = 0;                    /* frame destination offset   */
        g_dmaCTRLPKT1.PORTASGN  = 4;
        g_dmaCTRLPKT1.RDSIZE    = ACCESS_8_BIT;         /* read size                  */
        g_dmaCTRLPKT1.WRSIZE    = ACCESS_8_BIT;         /* write size                 */
        g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER;       /* transfer type              */
        g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;            /* address mode read          */
        g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED;           /* address mode write         */
        g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;         /* autoinit                   */

        /*Configure control packet for Channel 1*/
        g_dmaCTRLPKT2.SADD      = sciRxData;            /* source address             */
        g_dmaCTRLPKT2.DADD      = (uint32_t)RX_DATA;    /* destination  addr ss       */
        g_dmaCTRLPKT2.CHCTRL    = 0;                    /* channel control            */
        g_dmaCTRLPKT2.FRCNT    = PROTOCOL_SIZE;                  /* frame count                */
        g_dmaCTRLPKT2.ELCNT     = 1;                    /* element count              */
        g_dmaCTRLPKT2.ELDOFFSET = 0;                    /* element destination offset */
        g_dmaCTRLPKT2.ELSOFFSET = 0;                    /* element destination offset */
        g_dmaCTRLPKT2.FRDOFFSET = 0;                    /* frame destination offset   */
        g_dmaCTRLPKT2.FRSOFFSET = 0;                    /* frame destination offset   */
        g_dmaCTRLPKT2.PORTASGN  = 4;
        g_dmaCTRLPKT2.RDSIZE    = ACCESS_8_BIT;         /* read size                  */
        g_dmaCTRLPKT2.WRSIZE    = ACCESS_8_BIT;         /* write size                 */
        g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER;       /* transfer type              */
        g_dmaCTRLPKT2.ADDMODERD = ADDR_FIXED;           /* address mode read          */
        g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;            /* address mode write         */
        g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;         /* autoinit                   */

        /*Set control packet for channel 0 and 1*/
        dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);
        dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT2);

        /*Set dma channel 0 and 1 to trigger on hardware request*/
        dmaSetChEnable(DMA_CH0, DMA_HW);
        dmaSetChEnable(DMA_CH1, DMA_HW);

       /*Enable SCI Receive DMA Request*/
        sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;

        dmaEnableInterrupt(DMA_CH1, BTC);

    Next in the interrupt i do transfer like this way,

        /*tansfer enable*/
        dmaDisable();

        gioSetBit(gioPORTB, 5u, 1u);

        sciREG->CLEARINT = 0xffffffff;  
        sciREG->SETINT = SCI_SET_TX_DMA;

        /*delay berfore transmit*/

        int k = 0;
        for(k =0; k < 1000; k++)
        {
            __nop();
        }

        dmaEnable();

        while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
        dmaDisable();

        /*Delay to send last byte*/
        for(k =0; k < 1000; k++)
        {
            __nop();
        }

        gioSetBit(gioPORTB, 5u, 0u);

        sciREG->CLEARINT = 0xffffffff;
        sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
        dmaEnable();

    In this test, it can read alright data(receive is well). but, transmit data is not act. I don't know why  transmit not act.

    Receive DMA not stopped when sciREG->SETINT is cleared?

    -----------------------------------------

    I confirm that

        sciREG->CLEARINT = 0xffffffff;
        sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL; 

    is changed

    dmaReset(); -> dma reset

    sci_communication_with_dma_init(); -> dma re setting with first step

    then act well

    Would you explain why transmit DMA not act before initialize?

    Regards,

    Minwoo

  • Hello Minwoo,

        sciREG->CLEARINT = 0xffffffff;
        sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL; 

    The first instruction clears all the enabled interrupts and RX DMA/TX DMA bits. the 2nd instruction sets the RX DMA only. TX DMA is disabled.

  • Hello, QJ Wang

    Sci with DMA is act as slave.

    The code is act in DMA Interrupt function. (I think design of our board is connect Rx/Tx line and Rx always act.)

    The code action concept like this,

    1. DMAInterrupt - sci receive finish.

    2. Rx disable/Tx enable 

    3. Send data

    4. Tx disable/ Rx enable

    5. Wait next data(repeat 1~5)


        dmaDisable();

        /*tansfer enable*/

        gioSetBit(gioPORTB, 5u, 1u);

        sciREG->CLEARINT = 0xffffffff;  
        sciREG->SETINT = SCI_SET_TX_DMA;

        /*delay berfore transmit*/

        int k = 0;
        for(k =0; k < 1000; k++)
        {
            __nop();
        }

        dmaEnable();

        while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);

        /*block to send next block frame data*/

        dmaDisable();

        /*Delay to send last byte*/
        for(k =0; k < 1000; k++)
        {
            __nop();
        }

        /*Rx enable after Transmit*/

        gioSetBit(gioPORTB, 5u, 0u);

        sciREG->CLEARINT = 0xffffffff;
        sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
        dmaEnable();

    The green line is enable Tx/ disable Rx,  The red line is enable Rx/ disable Tx.

    Then, Rx act well, Tx is not act. 

    I read the data sheet as SCI_SET_RX_DMA -> Rx DMA request, and SCI_SET_TX_DMA -> Tx  DMA request.

    My questions are,

    1. Could I know why this problem is occurred?

    2. Is it impossible DMA trigger(DMA start and stop timing) by SCI_SET_RX_DMA/SCI_SET_TX_DMA?

    Regards,

    Minwoo

  • Hello Minwoo,

    Please refer to this app note for using SCI DMA to TX/RX data:

    http://www.ti.com/lit/an/spna213/spna213.pdf