crownstone / bluenet

Bluenet is the in-house firmware on Crownstone hardware. Functions: switching, dimming, energy monitoring, presence detection, indoor localization, switchcraft.
https://crownstone.rocks
91 stars 62 forks source link

ADC conversion using the driver in scan mode seems to swap/shift channels #33

Closed mrquincle closed 5 years ago

mrquincle commented 7 years ago

Nordic's comments about the ADC driver can be found online. Documentation on the SAADC driver can be found here.

The ADC driver has a low power mode in SDK 12. Does this disable EasyDMA when possible? (EasyDMA requires around 1.5mA).

The function nrf_drv_saadc_buffer_convert is called twice, once for each buffer. The first time nrf_saadc_buffer_init(p_buffer, size) is called. It sets the m_cb.adc_state state to NRF_SAADC_STATE_BUSY and m_cb.p_secondary_buffer to NULL (note that the latter variable is not set before, e.g. in nrf_drv_saadc_init, minor bug I think). The second time m_cb.p_secondary_buffer is NULL so nrf_saadc_buffer_init(p_buffer, size) is called again.

__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num)
{
    NRF_SAADC->RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC->RESULT.MAXCNT = num;
}

Apparently just calling that function twice is enough to use double buffering.

Two differences:

It seems very suspect that the order of the channels switches in the buffers. This might happen if we have an odd number of channels, but that is not the case. Is there a timing issue with EasyDMA?

Tests:

  1. Enable 8 channels to see what happens with scan mode in that situation.
  2. Remove all code that handles the buffer so that nrf_drv_saadc_buffer_convert can be called as quickly as possible.
  3. Try to reproduce with a minimal number of files.
  4. Update to SDK12.
vliedel commented 5 years ago

This was fixed, solution is documented here: https://github.com/crownstone/bluenet/blob/6ad42e77e06d675ff63fdff8f8fab2484d656ea1/docs/ADC.md