Bluenet  5.7.0
Bluenet, firmware for nRF52 smart home devices
Loading...
Searching...
No Matches
ADC Class Reference

Analog-Digital conversion. More...

#include <cs_ADC.h>

Inheritance diagram for ADC:
Collaboration diagram for ADC:

Public Member Functions

cs_ret_code_t init (const adc_config_t &config)
 Initialize ADC. More...
 
void start ()
 Start the ADC sampling. More...
 
void stop ()
 Stop the ADC sampling Only to be called from main thread. More...
 
void setDoneCallback (adc_done_cb_t callback)
 Set the callback which is called when a buffer is filled. More...
 
void setZeroCrossingCallback (adc_zero_crossing_cb_t callback)
 Set the callback which is called on a zero crossing interrupt. More...
 
void enableZeroCrossingInterrupt (adc_channel_id_t channel, int32_t zeroVal)
 Enable zero crossing detection on given channel, generating interrupts. More...
 
cs_ret_code_t changeChannel (adc_channel_id_t channel, adc_channel_config_t &config)
 Change channel config. More...
 
void handleEvent (event_t &event)
 Handle events. More...
 
void _restart ()
 Restart. More...
 
void _handleAdcDone (adc_buffer_id_t bufIndex)
 Handle buffer, called in main thread. More...
 
void _handleAdcLimitInterrupt (nrf_saadc_limit_t type)
 Called when the sampled value is above upper limit, or below lower limit. More...
 
void _handleAdcInterrupt ()
 Handles the ADC interrupt. More...
 

Static Public Member Functions

static ADCgetInstance ()
 Use static variant of singleton, no dynamic memory allocation. More...
 

Private Member Functions

 ADC ()
 Constructor. More...
 
 ADC (ADC const &)
 
void operator= (ADC const &)
 
bool dataCallbackRegistered ()
 
cs_ret_code_t initSaadc ()
 
cs_ret_code_t initChannel (adc_channel_id_t channel, adc_channel_config_t &config)
 Configure a channel. More...
 
void setLimitUp ()
 
void setLimitDown ()
 
cs_ret_code_t initBufferQueue ()
 
cs_ret_code_t fillSaadcQueue ()
 Try to add all queued buffers to the SAADC queue. More...
 
cs_ret_code_t _fillSaadcQueue (bool fromInterrupt)
 Same as fillSaadcQueue(), but without critical region enter/exit. More...
 
cs_ret_code_t addBufferToSaadcQueue (adc_buffer_id_t bufIndex)
 Puts a buffer in the SAADC queue. More...
 
cs_ret_code_t _addBufferToSaadcQueue (adc_buffer_id_t bufIndex)
 Same as addBufferToSaadcQueue(), but without critical region enter/exit. More...
 
void enterCriticalRegion ()
 Enter a region of code where variables are used that are also used in SAADC interrupts. More...
 
void exitCriticalRegion ()
 Exit a region of code where variables are used that are also used in SAADC interrupts. More...
 
void printQueues ()
 
void applyConfig ()
 
- Private Member Functions inherited from EventListener
 EventListener ()
 
virtual ~EventListener ()
 unregisters the listener. More...
 
virtual void handleEvent (event_t &event)=0
 Handle events. More...
 
void listen ()
 Registers this with the EventDispatcher. More...
 

Static Private Member Functions

static nrf_saadc_input_t getAdcPin (adc_pin_id_t pinNum)
 
static nrf_ppi_channel_t getPpiChannel (uint8_t index)
 
static nrf_saadc_event_t getLimitLowEvent (adc_channel_id_t channel)
 
static nrf_saadc_event_t getLimitHighEvent (adc_channel_id_t channel)
 
static nrf_gpiote_tasks_t getGpioteTaskOut (uint8_t index)
 

Private Attributes

bool _changeConfig = false
 Whether or not the config should be changed. More...
 
adc_config_t _config
 Configuration of this class. More...
 
adc_channel_config_result_t _channelResultConfigs [CS_ADC_NUM_CHANNELS]
 Resulting configuration of this class. More...
 
adc_buffer_seq_nr_t _bufSeqNr = 1
 Buffer sequence number. More...
 
nrf_ppi_channel_t _ppiChannelSample
 PPI channel to sample each tick, and count these. More...
 
nrf_ppi_channel_t _ppiChannelStart
 PPI channel used to start the SAADC on end event. More...
 
CircularBuffer< adc_buffer_id_t_bufferQueue
 Queue of buffers that are free to be added to the SAADC queue. More...
 
CircularBuffer< adc_buffer_id_t_saadcBufferQueue
 Keeps up which buffers that are queued in the SAADC peripheral. More...
 
bool _firstBuffer = true
 
adc_state_t _state = ADC_STATE_IDLE
 
volatile adc_saadc_state_t _saadcState = ADC_SAADC_STATE_IDLE
 Sate of the SAADC peripheral. More...
 
adc_done_cb_t _doneCallback = nullptr
 
adc_zero_crossing_cb_t _zeroCrossingCallback = nullptr
 The zero crossing callback. More...
 
adc_channel_id_t _zeroCrossingChannel = 0
 The channel which is checked for zero crossings. More...
 
nrf_saadc_event_t _eventLimitLow
 Cache limit event. More...
 
nrf_saadc_event_t _eventLimitHigh
 Cache limit event. More...
 
bool _zeroCrossingEnabled = false
 Keep up whether zero crossing is enabled. More...
 
uint32_t _lastZeroCrossUpTime = 0
 Store the RTC timestamp of the last upwards zero crossing. More...
 
int32_t _zeroValue = 0
 Store the zero value used to detect zero crossings. More...
 
int _criticalRegionEntered = 0
 Keep up number of nested critical regions entered. More...
 

Detailed Description

Analog-Digital conversion.

The ADC class can be used to convert an analog signal to a digital value on multiple pins. It's currently used for power measurement (measure voltage and current).

There is only one SAADC hardware peripheral, hence this class conforms to the singleton design pattern.

The constructor does NOT have arguments you might expect, such as the number of buffers to use, or the size of the buffers. These are all set through preprocessor macros. The ADC class requires access to the following macros (see below).

The timer used to get new samples on regular time intervals. The timer should be able to run on at least 2kHz to be able to get the fine-grained current and voltage data we want.

  • CS_ADC_TIMER The timer peripheral to use for the ADC peripheral.
  • CS_ADC_INSTANCE_INDEX The instance id of the timer, used by nrf_drv_config.
  • CS_ADC_TIMER_ID Number of the timer.

The buffers to be used internally. To have these buffers in the form of macros means that we can check at compile time if they are small enough with respect to the nRF52 memory limitations.

  • CS_ADC_NUM_BUFFERS The number of ADC buffers to use, should be at least 2.
  • CS_ADC_BUF_SIZE The size of the buffer (first time used in init()).

The pins:

  • CS_ADC_MAX_PINS The maximum number of pins available for ADC.

The sequence of events can be found in the uml diagrams under docs.

Constructor & Destructor Documentation

◆ ADC() [1/2]

ADC::ADC ( )
private

Constructor.

◆ ADC() [2/2]

ADC::ADC ( ADC const &  )
private

Member Function Documentation

◆ _addBufferToSaadcQueue()

cs_ret_code_t ADC::_addBufferToSaadcQueue ( adc_buffer_id_t  bufIndex)
private

Same as addBufferToSaadcQueue(), but without critical region enter/exit.

== Called from interrupt! ==

◆ _fillSaadcQueue()

cs_ret_code_t ADC::_fillSaadcQueue ( bool  fromInterrupt)
private

Same as fillSaadcQueue(), but without critical region enter/exit.

Parameters
[in]fromInterruptWhether this is called from an interrupt.

== Called from interrupt! ==

◆ _handleAdcDone()

void ADC::_handleAdcDone ( adc_buffer_id_t  bufIndex)

Handle buffer, called in main thread.

◆ _handleAdcInterrupt()

void ADC::_handleAdcInterrupt ( )

Handles the ADC interrupt.

End:

  • Restarts SAADC when no buffers are queued in SAADC,
  • Fills up SAADC buffer.

◆ _handleAdcLimitInterrupt()

void ADC::_handleAdcLimitInterrupt ( nrf_saadc_limit_t  type)

Called when the sampled value is above upper limit, or below lower limit.

◆ _restart()

void ADC::_restart ( )

Restart.

◆ addBufferToSaadcQueue()

cs_ret_code_t ADC::addBufferToSaadcQueue ( adc_buffer_id_t  bufIndex)
private

Puts a buffer in the SAADC queue.

Starts the SAADC when it's idle. Waits (blocking) for the SAADC to be started to queue another buffer.

Returns
  • ERR_SUCCESS when the buffer is queued in the SAADC.
  • ERR_NO_SPACE when there are already enough buffers queued in the SAADC, so the given buffer is not queued.
  • Other return codes for failures, the given buffer is not queued.

◆ applyConfig()

void ADC::applyConfig ( )
private

◆ changeChannel()

cs_ret_code_t ADC::changeChannel ( adc_channel_id_t  channel,
adc_channel_config_t config 
)

Change channel config.

Channel config will not change immediately.

Parameters
[in]channelChannel number.
[in]configThe channel config.
Returns
Return code.

◆ dataCallbackRegistered()

bool ADC::dataCallbackRegistered ( )
inlineprivate

◆ enableZeroCrossingInterrupt()

void ADC::enableZeroCrossingInterrupt ( adc_channel_id_t  channel,
int32_t  zeroVal 
)

Enable zero crossing detection on given channel, generating interrupts.

Parameters
[in]channelThe channel on which to check for zero crossings.
[in]zeroValThe value of zero.

◆ enterCriticalRegion()

void ADC::enterCriticalRegion ( )
private

Enter a region of code where variables are used that are also used in SAADC interrupts.

Make sure you exit once for each time you call enter.

◆ exitCriticalRegion()

void ADC::exitCriticalRegion ( )
private

Exit a region of code where variables are used that are also used in SAADC interrupts.

◆ fillSaadcQueue()

cs_ret_code_t ADC::fillSaadcQueue ( )
private

Try to add all queued buffers to the SAADC queue.

If the SAADC queue is now filled, stop the timeout timer.

Returns
ERR_SUCCESS when SAADC queue is full, and timeout timer has been stopped.
ERR_WRONG_STATE when SAADC queue is not filled, and timeout timer has been stopped.
ERR_NOT_FOUND when the SAADC queue is not full, and timeout timer has not been stopped.
Other return codes on failure.

◆ getAdcPin()

static nrf_saadc_input_t ADC::getAdcPin ( adc_pin_id_t  pinNum)
staticprivate

◆ getGpioteTaskOut()

static nrf_gpiote_tasks_t ADC::getGpioteTaskOut ( uint8_t  index)
staticprivate

◆ getInstance()

static ADC & ADC::getInstance ( )
inlinestatic

Use static variant of singleton, no dynamic memory allocation.

◆ getLimitHighEvent()

static nrf_saadc_event_t ADC::getLimitHighEvent ( adc_channel_id_t  channel)
staticprivate

◆ getLimitLowEvent()

static nrf_saadc_event_t ADC::getLimitLowEvent ( adc_channel_id_t  channel)
staticprivate

◆ getPpiChannel()

static nrf_ppi_channel_t ADC::getPpiChannel ( uint8_t  index)
staticprivate

◆ handleEvent()

void ADC::handleEvent ( event_t event)
virtual

Handle events.

This method is overloaded by all classes that derive from EventListener. They can receive an event_t struct and act upon it. These events are dispatched by the EventDispatcher.

Implements EventListener.

◆ init()

cs_ret_code_t ADC::init ( const adc_config_t config)

Initialize ADC.

Parameters
[in]configConfig struct.
Returns
Return code.

◆ initBufferQueue()

cs_ret_code_t ADC::initBufferQueue ( )
private

◆ initChannel()

cs_ret_code_t ADC::initChannel ( adc_channel_id_t  channel,
adc_channel_config_t config 
)
private

Configure a channel.

Parameters
[in]channelChannel number.
[in]configThe channel config.
Returns
Return code.

◆ initSaadc()

cs_ret_code_t ADC::initSaadc ( )
private

◆ operator=()

void ADC::operator= ( ADC const &  )
private

◆ printQueues()

void ADC::printQueues ( )
private

◆ setDoneCallback()

void ADC::setDoneCallback ( adc_done_cb_t  callback)

Set the callback which is called when a buffer is filled.

Parameters
[in]callbackFunction to be called when a buffer is filled with samples.

◆ setLimitDown()

void ADC::setLimitDown ( )
private

◆ setLimitUp()

void ADC::setLimitUp ( )
private

◆ setZeroCrossingCallback()

void ADC::setZeroCrossingCallback ( adc_zero_crossing_cb_t  callback)

Set the callback which is called on a zero crossing interrupt.

Currently only called when going from below to above the zero.

Parameters
[in]callbackFunction to be called on a zero crossing event. This function will run at interrupt level!

◆ start()

void ADC::start ( )

Start the ADC sampling.

◆ stop()

void ADC::stop ( )

Stop the ADC sampling Only to be called from main thread.

Member Data Documentation

◆ _bufferQueue

CircularBuffer<adc_buffer_id_t> ADC::_bufferQueue
private

Queue of buffers that are free to be added to the SAADC queue.

== Used in interrupt! ==

◆ _bufSeqNr

adc_buffer_seq_nr_t ADC::_bufSeqNr = 1
private

Buffer sequence number.

Increased each time a buffer is fully sampled.

◆ _changeConfig

bool ADC::_changeConfig = false
private

Whether or not the config should be changed.

== Used in interrupt! ==

◆ _channelResultConfigs

adc_channel_config_result_t ADC::_channelResultConfigs[CS_ADC_NUM_CHANNELS]
private

Resulting configuration of this class.

== Used in interrupt! ==

◆ _config

adc_config_t ADC::_config
private

Configuration of this class.

== Used in interrupt! ==

◆ _criticalRegionEntered

int ADC::_criticalRegionEntered = 0
private

Keep up number of nested critical regions entered.

◆ _doneCallback

adc_done_cb_t ADC::_doneCallback = nullptr
private

◆ _eventLimitHigh

nrf_saadc_event_t ADC::_eventLimitHigh
private

Cache limit event.

== Used in interrupt! ==

◆ _eventLimitLow

nrf_saadc_event_t ADC::_eventLimitLow
private

Cache limit event.

== Used in interrupt! ==

◆ _firstBuffer

bool ADC::_firstBuffer = true
private

◆ _lastZeroCrossUpTime

uint32_t ADC::_lastZeroCrossUpTime = 0
private

Store the RTC timestamp of the last upwards zero crossing.

== Used in interrupt! ==

◆ _ppiChannelSample

nrf_ppi_channel_t ADC::_ppiChannelSample
private

PPI channel to sample each tick, and count these.

Sample timer event COMPARE -> SAADC task SAMPLE -> Toggle sample test pin

◆ _ppiChannelStart

nrf_ppi_channel_t ADC::_ppiChannelStart
private

PPI channel used to start the SAADC on end event.

SAADC event END -> SAADC task START

◆ _saadcBufferQueue

CircularBuffer<adc_buffer_id_t> ADC::_saadcBufferQueue
private

Keeps up which buffers that are queued in the SAADC peripheral.

First buffer in queue is the one currently being (or going to be) filled with samples.

== Used in interrupt! ==

◆ _saadcState

volatile adc_saadc_state_t ADC::_saadcState = ADC_SAADC_STATE_IDLE
private

Sate of the SAADC peripheral.

== Used in interrupt! ==

◆ _state

adc_state_t ADC::_state = ADC_STATE_IDLE
private

◆ _zeroCrossingCallback

adc_zero_crossing_cb_t ADC::_zeroCrossingCallback = nullptr
private

The zero crossing callback.

== Used in interrupt! ==

◆ _zeroCrossingChannel

adc_channel_id_t ADC::_zeroCrossingChannel = 0
private

The channel which is checked for zero crossings.

== Used in interrupt! ==

◆ _zeroCrossingEnabled

bool ADC::_zeroCrossingEnabled = false
private

Keep up whether zero crossing is enabled.

== Used in interrupt! ==

◆ _zeroValue

int32_t ADC::_zeroValue = 0
private

Store the zero value used to detect zero crossings.

== Used in interrupt! ==


The documentation for this class was generated from the following file: