AnsweredAssumed Answered

Continious DMA with SPI1 TX k22

Question asked by Alexey Usoltsev on Feb 20, 2020
Latest reply on Feb 27, 2020 by Alexey Usoltsev

  Hello ,

In my project I send data to DAC through SPI. Also in the project i am using USB. Max samplrate of DAC is 1MHz, so if i use interrupt to load PUSHR of SPI i got stacked with USB.

 But there is a good news for me - i need only linear scan, so I can use timer that scans 16bit and DMA to load it to PUSHR. So i set up DMA_CH0 to load PIT_1 value to pushr and triggers on PIT0 each 1us. But the problem is that DMA works only 1 time even if i set up self-linking of the channel.

I can see if i start PUSHR load in the code, after the transmission ends DMA worked once to load PIT1_CVAL. And stops untill i call PUSHR write once again.

My basic pices of code is below:

 

void ini_dma()
{
    const edma_config_t dma_conf={
//            .enableContinuousLinkMode=1,
            .enableDebugMode=1,
    };
    //DMAMUX SET_Up
    CLOCK_EnableClock(kCLOCK_Dmamux0);
    DMAMUX_SetSource(DMAMUX0,dma_ch_0,kDmaRequestMux0SPI1);
    DMAMUX_EnableChannel(DMAMUX0,dma_ch_0); //dmamux =1 (PIT_CH0)
    DMAMUX_EnablePeriodTrigger(DMAMUX0,dma_ch_0);

 

    CLOCK_EnableClock(kCLOCK_Dma0);
    EDMA_Init(DMA0, &dma_conf);
    uint16_t abc=32000;
    DMA0->CR&=~DMA_CR_EMLM(1);
    DMA0->TCD[0].SADDR = (int)&(PIT->CHANNEL[1].CVAL);
//    DMA0->TCD[0].SADDR = (int)&(abc);
    DMA0->TCD[0].SOFF= 0; /* no address shift after each transfer */
    DMA0->TCD[0].SLAST = 0;
    DMA0->TCD[0].DADDR = (int)&(SPI1->PUSHR);
    DMA0->TCD[0].DOFF= 0;
    DMA0->TCD[0].DLAST_SGA= 0;
    DMA0->TCD[0].NBYTES_MLNO=2; //2bytes for 16bit PUSHR load

 


    DMA0->TCD[0].CITER_ELINKYES=DMA_CITER_ELINKYES_ELINK(1)|DMA_CITER_ELINKYES_LINKCH(0)|DMA_CITER_ELINKYES_CITER(1);
//    DMA0->TCD[0].CITER_ELINKNO=1; //single request
//    DMA0->TCD[0].BITER_ELINKNO=1; //single request
 DMA0->TCD[0].BITER_ELINKYES=DMA_BITER_ELINKYES_ELINK(1)|DMA_BITER_ELINKYES_LINKCH(0)|DMA_BITER_ELINKYES_BITER(1);
    DMA0->TCD[0].CSR|=DMA_CSR_ESG(0);

 

    DMA0->TCD[0].ATTR = DMA_ATTR_SSIZE(1)|DMA_ATTR_DSIZE(1)|DMA_ATTR_DMOD(0)|DMA_ATTR_SMOD(0);

 

    DMA0->ERQ=DMA_ERQ_ERQ0(1); //enable hardware request
    /* disable auto close request */
    DMA0->TCD[0].CSR &=~DMA_CSR_DREQ(1);
    DMA0->EEI=DMA_EEI_EEI0(1);//enable interrupt
    DMA0->TCD[0].CSR|=DMA_CSR_START(1)|DMA_CSR_INTMAJOR(1);
}

 

void ini_pit(){
    pit_config_t pit_conf;
    uint32_t freq = CLOCK_GetBusClkFreq();
    pit_conf.enableRunInDebug=0;

 

    CLOCK_EnableClock(kCLOCK_Pit0);
    PIT_SetTimerPeriod(PIT, kPIT_Chnl_0,freq/1000000 ); //1M freq

 

    PIT_Init(PIT, &pit_conf);
    PIT_StartTimer(PIT, kPIT_Chnl_0);
    PIT->CHANNEL[1].LDVAL=PIT_LDVAL_TSV(0xffff);
    PIT->CHANNEL[1].TCTRL|=PIT_TCTRL_CHN(1);
    PIT->CHANNEL[1].TCTRL|=PIT_TCTRL_TEN(1)|PIT_TCTRL_TIE(1);
}

Outcomes