Hi.
My first attempt to get SAADC to work was:
NRF_SAADC->INTENSET = (SAADC_INTEN_RESULTDONE_Enabled << SAADC_INTEN_RESULTDONE_Pos) | //A result is ready to get transferred to RAM.
(SAADC_INTEN_DONE_Enabled <<SAADC_INTEN_DONE_Pos) | //A conversion task has been completed
(SAADC_INTEN_END_Enabled << SAADC_INTEN_END_Pos) | // The ADC has filled up the Result buffer
(SAADC_INTEN_STARTED_Enabled << SAADC_INTEN_STARTED_Pos) |
(SAADC_INTEN_STOPPED_Enabled << SAADC_INTEN_STOPPED_Pos);
//NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_AnalogInput0 << SAADC_CH_PSELP_PSELP_Pos;
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD << SAADC_CH_PSELP_PSELP_Pos;
// AIN0 as Negative for differential channel
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
//ADC range = 0.6V/(1/6) = 3.6V
NRF_SAADC->CH[0].CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) |
(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
(SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) |
(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos) |
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) |
(SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos);
while (NRF_SAADC->STATUS & 0x01); // Wait while ADC busy
NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit << SAADC_RESOLUTION_VAL_Pos;
NRF_SAADC->RESULT.PTR = adc_result; // Pointer to result variable
NRF_SAADC->RESULT.MAXCNT = 1;
NRF_SAADC->ENABLE = 0x01;
NVIC_EnableIRQ(SAADC_IRQn);
// Calibrate the SAADC (only needs to be done once in a while)
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0);
NRF_SAADC->EVENTS_CALIBRATEDONE = 0;
while (NRF_SAADC->STATUS == (SAADC_STATUS_STATUS_Busy <<SAADC_STATUS_STATUS_Pos));
NRF_SAADC->TASKS_START = 1;
In SAADC_IRQHandler after catching EVENTS_STARTED i run samling by NRF_SAADC->TASKS_SAMPLE = 1; and wait for EVENTS_END interupt
i've tryed to use adc_result as uint32_t, as int, as volatile but alway in SAADC_IRQHandler in EVENTS_END get nothing even if i set VDD as an input
Then i've tryed to use the part from example:
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD );//NRF_SAADC_INPUT_AIN0);
err_code = nrf_drv_saadc_init(NULL, saadc_callback);
err_code = nrf_drv_saadc_channel_init(0, &channel_config);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], 2);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], 2);
nrf_drv_saadc_sample();
with the very same result in saadc_callback(nrf_drv_saadc_evt_t const * p_event) - i've always getting zero, or more correctly SAADC not writing to buffer, i've wrote to buffer
fake values like 55 and 99 and got those in handler intead of the real results of ADC conversion.
Looks like EasyDMA is just ignoring my buffer in both cases. should i somewhere in config expliciltly enable easydma module?
I'm using Keil with their implementation of SDK from Packs Installer, maybe it's corrupted or i need do something in options?