This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SAADC Easy DMA with 1 Channel

I am using SAADC and reading in 1 analog channel. The data sheet says that scan mode is enabled when 2 or more channels are turned on. What if I am only using 1 channel ? How can I turn on scan mode and have the DMA store the results in memory?

Right now with one channel selected, the results are put in memory by the DMA, but the buffer pointer is not incrementing. As soon as I add another channel, the buffer pointer begins to increment.

  • Do you mean that you have a buffer with a size > 1, and you only get one sample in the buffer? Could you post some code showing how you do sampling?

  • uint32_t adc_results[1024]={0};

    void setup_adc() { NRF_SAADC ->ENABLE = 0;

    	NRF_SAADC ->RESOLUTION = 2 ; //12 bit resolution
    	NRF_SAADC ->OVERSAMPLE = 0; //bypass over sampling
    
    	NRF_SAADC ->RESULT.PTR = (uint32_t)&adc_results[0];
    	NRF_SAADC ->RESULT.MAXCNT = 512; 
    	NRF_SAADC ->SAMPLERATE= 0x000010FF;  //fast sample rate auto 
    
    	NRF_SAADC ->CH[0].CONFIG = 	(SAADC_CH_CONFIG_BURST_Disabled << SAADC_CH_CONFIG_BURST_Pos) | \
    															(SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos ) | \
    															(SAADC_CH_CONFIG_TACQ_10us << SAADC_CH_CONFIG_TACQ_Pos ) | \
    															(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) | \
    															(SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos ) | \
    															(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos ) | \
    															(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos ) ;
    
    	NRF_SAADC ->CH[0].LIMIT = 0;
    	NRF_SAADC ->CH[0].PSELN = 0;
    	NRF_SAADC ->CH[0].PSELP = 2;
    
    	NRF_SAADC ->INTEN = 0x0000000E ; //enable int for end
    	NRF_SAADC ->ENABLE = 1;
    	NRF_SAADC ->TASKS_START = 1;
    	
    

    }

    void start_adc() {

    //NRF_SAADC ->TASKS_START = 1;
    NRF_SAADC ->TASKS_SAMPLE = 1;
    

    }

    void SAADC_IRQHandler (void) {

    NRF_SAADC ->INTEN = 0x00000000 ; //disable int for end
    NRF_SAADC ->EVENTS_END = 0; //clear event
    NRF_SAADC ->EVENTS_DONE = 0; //clear event
    NRF_SAADC ->EVENTS_RESULTDONE = 0; //clear event
    //NRF_SAADC ->TASKS_START = 1;
        //NRF_SAADC ->TASKS_SAMPLE = 1;
    NRF_SAADC ->RESULT.PTR = (uint32_t)&adc_results[0];
    NRF_SAADC ->INTEN = 0x00000002 ; //enable int for end
    

    }

  • So, for some reason it started working, but for some reason I can not get the interrupt to trigger to do another sample. I would like it to continuously sample the one channel. I enabled all the interrupts and still nothing.

  • Do you call NVIC_EnableIRQ(SAADC_IRQn); in your code to register the peripheral with the interrupt controller? I would also recommend that you check out this example, which is written by one of my colleagues. You can change it to run continuously by doing the changes as described in this thread.

Related