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.

RM57L843: SPI DMA Loopback mode

Part Number: RM57L843
Other Parts Discussed in Thread: HALCOGEN

Hi,

I have created the new project and follow the steps as mentioned in the halcogen "mibspiDma.c" but it is not working,

as i observed load data is successful on TXDATA, but after running while(1) for more than 1sec there is no data in RXDATA buffer,

Please let me know if i missed any setting in halcogen!

Thank you,

Vikas N.

  • Hi Vikas,

    The MibSPI example used interrupt mode: transfer complete.

    1.  Enable the MIBSPIx interrupt in the MIBSPIx VIM Channel tab. Each MibSPI has two VIM channels: MibSPIx High or MibSPIx Low

    2. You need to enable the interrupt:

       mibspiEnableGroupNotification(mibSPIx, TGx, level);

       where level can be 0 (low level priority) or 1 (high level priority)

        MibSPIx High channel is enabled, please use 1 for level 

    3. Enable IRQ interrupt in your code

  • Hi QJ Wang,

    I have added the steps as you mentioned, pls find the code here,

    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    /* Include Files */
    
    #include "HL_sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #include "HL_mibspi.h"
    #include "HL_sys_dma.h"
    #include "HL_sys_core.h"
    
    /* example data Pattern configuration */
    #define D_SIZE      128
    
    void loadDataPattern(uint32 psize, uint16* pptr);
    void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi);
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
    void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel);
    
    #pragma SET_DATA_SECTION(".sharedRAM")
    uint16 TXDATA[D_SIZE];         /* transmit buffer in sys ram */
    uint16 RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
    #pragma SET_DATA_SECTION()
    
    boolean bIsMibspiDataReceived_g=0;
    g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;    /* dma control packet configuration stack */
    /* USER CODE END */
    
    /** @fn void main(void)
    *   @brief Application main function
    *   @note This function is empty by default.
    *
    *   This function is called after startup.
    *   The user can use this function to implement the application.
    */
    
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        _enable_IRQ_interrupt_();
    
       /* - creating a data chunk in system ram to start with ... */
       loadDataPattern(D_SIZE,&TXDATA[0]);
    
       /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/
       mibspiInit();
       mibspiEnableGroupNotification(mibspiREG1,0u,1u); /* Enable group notification for mibspi1 interface*/
    
    
       dmaEnableInterrupt(DMA_CH0, FTC, DMA_INTA);
       dmaEnableInterrupt(DMA_CH1, FTC, DMA_INTA);
    
       /* - enabling loopback ( this is to emulate data transfer without external wires */
       mibspiEnableInternalLoopback(mibspiREG1);
    
       /* - configuring dma control packets   */
       g_dmaCTRLPKT1.SADD      = (uint32)TXDATA;    /* source address             */
       g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM1->tx[0].data);    /* destination  address       */
       g_dmaCTRLPKT1.CHCTRL    = 0;                 /* channel control            */
       g_dmaCTRLPKT1.FRCNT     = 1;                 /* frame count                */
       g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
       g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* 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  = PORTA_READ_PORTB_WRITE;
       g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
       g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
       g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
       g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
       g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
       g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    
       g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM1->rx[0].data);    /* source address             */
       g_dmaCTRLPKT2.DADD      = (uint32)RXDATA;    /* destination  address       */
       g_dmaCTRLPKT2.CHCTRL    = 0;                 /* channel control            */
       g_dmaCTRLPKT2.FRCNT     = 1;                 /* frame count                */
       g_dmaCTRLPKT2.ELCNT     = D_SIZE;             /* element count              */
       g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
       g_dmaCTRLPKT2.ELSOFFSET = 4;                 /* element destination offset */
       g_dmaCTRLPKT2.FRDOFFSET = 0;                 /* frame destination offset   */
       g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
       g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
       g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
       g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
       g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
       g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
       g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
       g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    
       /* upto 32 control packets are supported. */
    
       /* - setting dma control packets */
       dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2);
       dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1);
    
       /* - setting the dma channel to trigger on h/w request */
       dmaSetChEnable(DMA_CH0, DMA_HW);
       dmaSetChEnable(DMA_CH1, DMA_HW);
    
       /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1     */
       /* - refer to the device data sheet dma request source for mibspi tx/rx  */
       mibspiDmaConfig(mibspiREG1,0,0,1);
    
       dmaEnable();
    
       unsigned int loop;
    
       for(loop=0;loop<5000;loop++);
    
       /* - start the mibspi transfer tg 0 */
       mibspiTransfer(mibspiREG1,0 );
    
    
       for(loop=0;loop<5000;loop++);
    
     //  mibspiGetData(mibspiREG1, 0, RXDATA);
       while(1); /* loop forever */
    
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi )
    {
        /* enabling internal loopback */
        mibspi->GCR1 |= 1U << 16U;
    }
    /* MIBSPI interrupt notification */
    void mibspiGroupNotification(mibspiBASE_t *mibspi, uint32 group)
    {
    
        if( mibspi == mibspiREG1 )
        {
            bIsMibspiDataReceived_g = TRUE;
        }
    
    }
    
    void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
    {
        uint32 bufid  = D_SIZE - 1;
        uint32 icount = 0;
    
        /* setting transmit and receive channels */
        mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);
    
        /* enabling transmit and receive dma */
        mibspi->DMACTRL[channel] |=  0x8000C000;
    
        /* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
        mibspi->DMACTRL[channel] |=  (icount << 8) |(bufid<<24);
    
    }
    
    
    void loadDataPattern(uint32 psize, uint16* pptr)
    {
        int i;
        for(i=0;i<psize;i++)
        {
            TXDATA[i] = i;
        }
     }
    /* USER CODE END */
    

    Halcogen Seeting: 

    And the Mibspi1 setting is as per the Haclogen Help example in "Example_mibspiDma.c"

    please let me know or suggest /provide me any code example in loopback mode - SPIDMA 

     

    Thank you,

    Vikas N

  • Hello QJ Wang,

    I have added the mibspiEnableGroupNotification(mibspiREG1,0u,1u); and enable the MIBSPIx interrupt both, High and low in Halcogen,

    find the code and Halcogen Setting, Please let me know is there is anything i missed or Is there is any example to try,

     

    /* USER CODE BEGIN (0) */ /* USER CODE END */ /* Include Files */ #include "HL_sys_common.h" /* USER CODE BEGIN (1) */ #include "HL_mibspi.h" #include "HL_sys_dma.h" #include "HL_sys_core.h" /* example data Pattern configuration */ #define D_SIZE 128 void loadDataPattern(uint32 psize, uint16* pptr); void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi); void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize); void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel); #pragma SET_DATA_SECTION(".sharedRAM") uint16 TXDATA[D_SIZE]; /* transmit buffer in sys ram */ uint16 RXDATA[D_SIZE]= {0}; /* receive buffer in sys ram */ #pragma SET_DATA_SECTION() boolean bIsMibspiDataReceived_g=0; g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2; /* dma control packet configuration stack */ /* USER CODE END */ /** @fn void main(void) * @brief Application main function * @note This function is empty by default. * * This function is called after startup. * The user can use this function to implement the application. */ /* USER CODE BEGIN (2) */ /* USER CODE END */ int main(void) { /* USER CODE BEGIN (3) */ _enable_IRQ_interrupt_(); /* - creating a data chunk in system ram to start with ... */ loadDataPattern(D_SIZE,&TXDATA[0]); /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/ mibspiInit(); mibspiEnableGroupNotification(mibspiREG1,0u,1u); /* Enable group notification for mibspi1 interface*/ dmaEnableInterrupt(DMA_CH0, FTC, DMA_INTA); dmaEnableInterrupt(DMA_CH1, FTC, DMA_INTA); /* - enabling loopback ( this is to emulate data transfer without external wires */ mibspiEnableInternalLoopback(mibspiREG1); /* - configuring dma control packets */ g_dmaCTRLPKT1.SADD = (uint32)TXDATA; /* source address */ g_dmaCTRLPKT1.DADD = (uint32)&(mibspiRAM1->tx[0].data); /* destination address */ g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */ g_dmaCTRLPKT1.FRCNT = 1; /* frame count */ g_dmaCTRLPKT1.ELCNT = D_SIZE; /* element count */ g_dmaCTRLPKT1.ELDOFFSET = 4; /* 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 = PORTA_READ_PORTB_WRITE; g_dmaCTRLPKT1.RDSIZE = ACCESS_16_BIT; /* read size */ g_dmaCTRLPKT1.WRSIZE = ACCESS_16_BIT; /* write size */ g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER ; /* transfer type */ g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */ g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET; /* address mode write */ g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_ON; /* autoinit */ g_dmaCTRLPKT2.SADD = (uint32)&(mibspiRAM1->rx[0].data); /* source address */ g_dmaCTRLPKT2.DADD = (uint32)RXDATA; /* destination address */ g_dmaCTRLPKT2.CHCTRL = 0; /* channel control */ g_dmaCTRLPKT2.FRCNT = 1; /* frame count */ g_dmaCTRLPKT2.ELCNT = D_SIZE; /* element count */ g_dmaCTRLPKT2.ELDOFFSET = 0; /* element destination offset */ g_dmaCTRLPKT2.ELSOFFSET = 4; /* element destination offset */ g_dmaCTRLPKT2.FRDOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT2.FRSOFFSET = 0; /* frame destination offset */ g_dmaCTRLPKT2.PORTASGN = PORTB_READ_PORTA_WRITE; g_dmaCTRLPKT2.RDSIZE = ACCESS_16_BIT; /* read size */ g_dmaCTRLPKT2.WRSIZE = ACCESS_16_BIT; /* write size */ g_dmaCTRLPKT2.TTYPE = FRAME_TRANSFER ; /* transfer type */ g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET; /* address mode read */ g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1; /* address mode write */ g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_ON; /* autoinit */ /* upto 32 control packets are supported. */ /* - setting dma control packets */ dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2); dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1); /* - setting the dma channel to trigger on h/w request */ dmaSetChEnable(DMA_CH0, DMA_HW); dmaSetChEnable(DMA_CH1, DMA_HW); /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1 */ /* - refer to the device data sheet dma request source for mibspi tx/rx */ mibspiDmaConfig(mibspiREG1,0,0,1); dmaEnable(); unsigned int loop; for(loop=0;loop<5000;loop++); /* - start the mibspi transfer tg 0 */ mibspiTransfer(mibspiREG1,0 ); for(loop=0;loop<5000;loop++); // mibspiGetData(mibspiREG1, 0, RXDATA); while(1); /* loop forever */ /* USER CODE END */ return 0; } /* USER CODE BEGIN (4) */ void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi ) { /* enabling internal loopback */ mibspi->GCR1 |= 1U << 16U; } /* MIBSPI interrupt notification */ void mibspiGroupNotification(mibspiBASE_t *mibspi, uint32 group) { if( mibspi == mibspiREG1 ) { bIsMibspiDataReceived_g = TRUE; } } void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel) { uint32 bufid = D_SIZE - 1; uint32 icount = 0; /* setting transmit and receive channels */ mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16); /* enabling transmit and receive dma */ mibspi->DMACTRL[channel] |= 0x8000C000; /* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */ mibspi->DMACTRL[channel] |= (icount << 8) |(bufid<<24); } void loadDataPattern(uint32 psize, uint16* pptr) { int i; for(i=0;i<psize;i++) { TXDATA[i] = i; } } /* USER CODE END */

  • Hello QJ Wang,

    I have added the loop in same code, after mibspiTransfer(mibspiREG1,0 ) as,

    mibspiTransfer(mibspiREG1,0 );
    while(!(mibspiIsTransferComplete(mibspiREG1,0)))
    {
    };

    The mibspiIsTransferComplete API is always returns the FALSE,

    Thank you,

    Vikas N.

  • Hi Vikas,

    Have you make the example code work?