Bluenet
5.7.0
Bluenet, firmware for nRF52 smart home devices
|
Analog-Digital conversion. More...
#include <cs_ADC.h>
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 ADC & | getInstance () |
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 () |
![]() | |
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... | |
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.
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.
The pins:
The sequence of events can be found in the uml diagrams under docs.
|
private |
Constructor.
|
private |
Same as addBufferToSaadcQueue(), but without critical region enter/exit.
== Called from interrupt! ==
|
private |
Same as fillSaadcQueue(), but without critical region enter/exit.
[in] | fromInterrupt | Whether this is called from an interrupt. |
== Called from interrupt! ==
void ADC::_handleAdcDone | ( | adc_buffer_id_t | bufIndex | ) |
Handle buffer, called in main thread.
void ADC::_handleAdcInterrupt | ( | ) |
Handles the ADC interrupt.
End:
void ADC::_handleAdcLimitInterrupt | ( | nrf_saadc_limit_t | type | ) |
Called when the sampled value is above upper limit, or below lower limit.
void ADC::_restart | ( | ) |
Restart.
|
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.
|
private |
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.
[in] | channel | Channel number. |
[in] | config | The channel config. |
|
inlineprivate |
void ADC::enableZeroCrossingInterrupt | ( | adc_channel_id_t | channel, |
int32_t | zeroVal | ||
) |
Enable zero crossing detection on given channel, generating interrupts.
[in] | channel | The channel on which to check for zero crossings. |
[in] | zeroVal | The value of zero. |
|
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.
|
private |
Exit a region of code where variables are used that are also used in SAADC interrupts.
|
private |
Try to add all queued buffers to the SAADC queue.
If the SAADC queue is now filled, stop the timeout timer.
|
staticprivate |
|
staticprivate |
|
inlinestatic |
Use static variant of singleton, no dynamic memory allocation.
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
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.
cs_ret_code_t ADC::init | ( | const adc_config_t & | config | ) |
|
private |
|
private |
Configure a channel.
[in] | channel | Channel number. |
[in] | config | The channel config. |
|
private |
|
private |
|
private |
void ADC::setDoneCallback | ( | adc_done_cb_t | callback | ) |
Set the callback which is called when a buffer is filled.
[in] | callback | Function to be called when a buffer is filled with samples. |
|
private |
|
private |
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.
[in] | callback | Function to be called on a zero crossing event. This function will run at interrupt level! |
void ADC::start | ( | ) |
Start the ADC sampling.
void ADC::stop | ( | ) |
Stop the ADC sampling Only to be called from main thread.
|
private |
Queue of buffers that are free to be added to the SAADC queue.
== Used in interrupt! ==
|
private |
Buffer sequence number.
Increased each time a buffer is fully sampled.
|
private |
Whether or not the config should be changed.
== Used in interrupt! ==
|
private |
Resulting configuration of this class.
== Used in interrupt! ==
|
private |
Configuration of this class.
== Used in interrupt! ==
|
private |
Keep up number of nested critical regions entered.
|
private |
|
private |
Cache limit event.
== Used in interrupt! ==
|
private |
Cache limit event.
== Used in interrupt! ==
|
private |
|
private |
|
private |
PPI channel to sample each tick, and count these.
Sample timer event COMPARE -> SAADC task SAMPLE -> Toggle sample test pin
|
private |
PPI channel used to start the SAADC on end event.
SAADC event END -> SAADC task START
|
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! ==
|
private |
Sate of the SAADC peripheral.
== Used in interrupt! ==
|
private |
|
private |
The zero crossing callback.
== Used in interrupt! ==
|
private |
The channel which is checked for zero crossings.
== Used in interrupt! ==
|
private |
Keep up whether zero crossing is enabled.
== Used in interrupt! ==
|
private |
Store the zero value used to detect zero crossings.
== Used in interrupt! ==