AnsweredAssumed Answered

kinetis KL05 DMA based ADC triggering

Question asked by Barry Butsers on Mar 16, 2015
Latest reply on Nov 17, 2015 by Steve Kroon

Hello,

I am working on a BLDC motor control project based on a KL05Z32 MCU. The application needs ADC sampling at a rate of 100kSamples/second.

I have built a solution based on chaining the PIT, DMA and the ADC. The PIT is running at 100kHz, it triggers DMA channel 0 to load one of 4 different configurations from a buffer to the SC1A register of ADC0. This starts the ADC conversion. The result of the measurement is placed in a buffer by another DMA channel.

 

This setup is working fine, as long as the first DMA0 request is running. I know I have to make sure the byte count register is not zero when the PIT triggers DMA0, but this is not working at the moment. The idea to achieve this, is by placing 0xFFFFC (= the highest allowed value which is a multiple of four) in the BCR register in the DMA0 complete interrupt. This trick was suggested in the topic stated below:

Re: PIT trigger the DMA and the DMA transfer data to the DAC doesn't work

 

After the BCR update in the interrupt, the configuration error is set.

Is there a way to fix this problem?

 

I attached the code from my project, note that the modulo buffers are disabled for easier testing.

The controller i`m using has mask 1N96F.

 

Thanks in advance

 

void DMA0_init(void) 
{
    //use DMA channel 0 to move channel settings / triggering to ADC
    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
    
    DMAMUX0_CHCFG0 = DMAMUX_CHCFG_SOURCE(0x00); //disable DMAMux modules before initialization
    DMA_DSR_BCR0 = DMA_DSR_BCR_BCR(0xFFFFC);//(); //highest allowed multiple of 4
    DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK;
    // Clear pending errors and/or the done bit 
    if (((DMA_DSR_BCR0 & DMA_DSR_BCR_DONE_MASK) == DMA_DSR_BCR_DONE_MASK)| ((DMA_DSR_BCR0 & DMA_DSR_BCR_BES_MASK) == DMA_DSR_BCR_BES_MASK)
       | ((DMA_DSR_BCR0 & DMA_DSR_BCR_BED_MASK) == DMA_DSR_BCR_BED_MASK) | ((DMA_DSR_BCR0 & DMA_DSR_BCR_CE_MASK) == DMA_DSR_BCR_CE_MASK))
       DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK;
    
    DMA_SAR0 = (uint32_t)&u32ADCcontrol[0];
    DMA_DAR0 = (uint32_t)&ADC0_SC1A;
    
   
    DMA_DCR0 = DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK |  DMA_DCR_EINT_MASK | DMA_DCR_SSIZE(0x00) | DMA_DCR_DSIZE(0x00) | DMA_DCR_SMOD(0x00) | DMA_DCR_DMOD(0x00) | DMA_DCR_LINKCC(0x00) | DMA_DCR_LCH1(0x00);
    DMAMUX0_CHCFG0 = DMAMUX_CHCFG_TRIG_MASK | DMAMUX_CHCFG_SOURCE(60); //use always enabled channel
    
    enable_irq(INT_DMA0, 0);
}

void DMA0_IRQHandler()
{
    GPIOA_PSOR = (1 << 9);
        
    DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK;
            
    DMA_DSR_BCR0 = DMA_DSR_BCR_BCR(0xFFFFC) | DMA_DSR_BCR_DONE_MASK;
        
    GPIOA_PCOR = (1 << 9);
}

Outcomes