mirror of https://github.com/ARMmbed/mbed-os.git
Merge branch 'nordic_sdk_integration' of https://github.com/ARMmbed/mbed-nordic into hal_improvements
# Conflicts: # hal/targets.jsonpull/2234/head
commit
fce8a300d1
|
@ -1773,6 +1773,6 @@
|
|||
"NRF52_PAN_62",
|
||||
"NRF52_PAN_63"
|
||||
],
|
||||
"device_has": ["ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"]
|
||||
"device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH", "SPISLAVE"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ void analogin_init(analogin_t *obj, PinName pin)
|
|||
ret_code_t ret_code;
|
||||
// p_config, event_handler
|
||||
ret_code = nrf_drv_adc_init(NULL , NULL); // select blocking mode
|
||||
MBED_ASSERT(ret_code == NRF_SUCCESS);
|
||||
MBED_ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_INVALID_STATE)); //NRF_ERROR_INVALID_STATE expected for multiple channels used.
|
||||
}
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj)
|
||||
|
|
|
@ -13,68 +13,69 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed_assert.h"
|
||||
#include "analogin_api.h"
|
||||
#include "cmsis.h"
|
||||
#include "pinmap.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "nrf_drv_saadc.h"
|
||||
|
||||
#ifdef DEVICE_ANALOGIN
|
||||
|
||||
#define ANALOGIN_MEDIAN_FILTER 1
|
||||
#define ADC_10BIT_RANGE 0x3FF
|
||||
#define ADC_RANGE ADC_10BIT_RANGE
|
||||
#define ADC_12BIT_RANGE 0xFFF
|
||||
#define ADC_RANGE ADC_12BIT_RANGE
|
||||
|
||||
static const PinMap PinMap_ADC[] = {
|
||||
{p1, ADC0_0, 4},
|
||||
{p2, ADC0_0, 8},
|
||||
{p3, ADC0_0, 16},
|
||||
{p4, ADC0_0, 32},
|
||||
{p5, ADC0_0, 64},
|
||||
{p6, ADC0_0, 128},
|
||||
{NC, NC, 0}
|
||||
static void analog_in_event_handler(nrf_drv_saadc_evt_t const *p_event)// type of nrf_drv_saadc_event_handler_t
|
||||
{
|
||||
(void) p_event;
|
||||
}
|
||||
|
||||
static const nrf_drv_saadc_config_t saadc_config =
|
||||
{
|
||||
.resolution = NRF_SAADC_RESOLUTION_12BIT,
|
||||
.oversample = NRF_SAADC_OVERSAMPLE_DISABLED,
|
||||
.interrupt_priority = APP_IRQ_PRIORITY_LOW
|
||||
};
|
||||
|
||||
void analogin_init(analogin_t *obj, PinName pin)
|
||||
{
|
||||
// TODO: usage on nrf52 ?
|
||||
#if 0
|
||||
int analogInputPin = 0;
|
||||
const PinMap *map = PinMap_ADC;
|
||||
|
||||
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); //(NRF_ADC_Type *)
|
||||
MBED_ASSERT(obj->adc != (ADCName)NC);
|
||||
|
||||
while (map->pin != NC) {
|
||||
if (map->pin == pin) {
|
||||
analogInputPin = map->function;
|
||||
break;
|
||||
}
|
||||
map++;
|
||||
}
|
||||
obj->adc_pin = (uint8_t)analogInputPin;
|
||||
|
||||
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
|
||||
NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
|
||||
(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
|
||||
(ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) |
|
||||
(analogInputPin << ADC_CONFIG_PSEL_Pos) |
|
||||
(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
|
||||
#endif
|
||||
ret_code_t ret_code;
|
||||
|
||||
ret_code = nrf_drv_saadc_init(&saadc_config, analog_in_event_handler);
|
||||
MBED_ASSERT(((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_INVALID_STATE))); //NRF_ERROR_INVALID_STATE expected for multiple channels used.
|
||||
|
||||
uint8_t saadcIn = nrf_drv_saadc_gpio_to_ain(pin);
|
||||
MBED_ASSERT(saadcIn != NRF_SAADC_INPUT_DISABLED);
|
||||
|
||||
obj->adc = ADC0_0; // only one instance of ADC in nRF52 SoC
|
||||
obj->adc_pin = saadcIn - 1;
|
||||
|
||||
nrf_saadc_channel_config_t channel_config =
|
||||
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(saadcIn); //Single ended, negative input to ADC shorted to GND.
|
||||
|
||||
ret_code = nrf_drv_saadc_channel_init(obj->adc_pin, &channel_config);
|
||||
MBED_ASSERT(ret_code == NRF_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
uint16_t analogin_read_u16(analogin_t *obj)
|
||||
{
|
||||
// TODO: usage on nrf52 ?
|
||||
#if 0
|
||||
NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
|
||||
NRF_ADC->CONFIG |= obj->adc_pin << ADC_CONFIG_PSEL_Pos;
|
||||
NRF_ADC->TASKS_START = 1;
|
||||
while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
|
||||
int16_t adc_value;
|
||||
ret_code_t ret_code;
|
||||
|
||||
ret_code = nrf_drv_saadc_sample_convert(obj->adc_pin, &adc_value);
|
||||
MBED_ASSERT(ret_code == NRF_SUCCESS);
|
||||
|
||||
if (adc_value < 0)
|
||||
{
|
||||
// Even in the single ended mode measured value can be {-0}. Saturation for avoid casting to a big integer.
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (uint16_t) adc_value;
|
||||
}
|
||||
|
||||
return (uint16_t)NRF_ADC->RESULT; // 10 bit
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
float analogin_read(analogin_t *obj)
|
||||
|
|
|
@ -0,0 +1,509 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nrf_drv_saadc.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nordic_common.h"
|
||||
#include "nrf_drv_common.h"
|
||||
#include "app_util_platform.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_STATE_IDLE = 0,
|
||||
NRF_SAADC_STATE_BUSY = 1
|
||||
} nrf_saadc_state_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nrf_saadc_input_t pselp;
|
||||
nrf_saadc_input_t pseln;
|
||||
} nrf_saadc_psel_buffer;
|
||||
|
||||
static const nrf_drv_saadc_config_t m_default_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
|
||||
|
||||
/** @brief SAADC control block.*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_saadc_event_handler_t event_handler; ///< Event handler function pointer.
|
||||
volatile nrf_saadc_value_t * p_buffer; ///< Sample buffer.
|
||||
volatile uint16_t buffer_size; ///< Size of the sample buffer.
|
||||
#ifdef NRF52_PAN_28
|
||||
volatile uint16_t buffer_pos; ///< Current sample buffer position.
|
||||
#endif
|
||||
volatile nrf_saadc_value_t * p_secondary_buffer; ///< Secondary sample buffer.
|
||||
uint32_t limits_enabled_flags; ///< Enabled limits flags.
|
||||
uint16_t secondary_buffer_size; ///< Size of the secondary buffer.
|
||||
nrf_saadc_psel_buffer psel[NRF_SAADC_CHANNEL_COUNT]; ///< Pin configurations of SAADC channels.
|
||||
nrf_drv_state_t state; ///< Driver initialization state.
|
||||
nrf_saadc_state_t adc_state; ///< State of the SAADC.
|
||||
#ifdef NRF52_PAN_28
|
||||
uint8_t scan_pos; ///< Current channel scanning position.
|
||||
#endif
|
||||
uint8_t active_channels; ///< Number of enabled SAADC channels.
|
||||
} nrf_drv_saadc_cb_t;
|
||||
|
||||
static nrf_drv_saadc_cb_t m_cb;
|
||||
|
||||
#define LOW_LIMIT_TO_FLAG(channel) ((2*channel+1))
|
||||
#define HIGH_LIMIT_TO_FLAG(channel) ((2*channel))
|
||||
#define FLAG_IDX_TO_EVENT(idx) ((nrf_saadc_event_t)((uint32_t)NRF_SAADC_EVENT_CH0_LIMITH+4*idx))
|
||||
#define LIMIT_EVENT_TO_CHANNEL(event)(uint8_t)(((uint32_t)event-(uint32_t)NRF_SAADC_EVENT_CH0_LIMITH)/8)
|
||||
#define LIMIT_EVENT_TO_LIMIT_TYPE(event)((((uint32_t)event-(uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) & 4) ? \
|
||||
NRF_SAADC_LIMIT_LOW : NRF_SAADC_LIMIT_HIGH)
|
||||
#define HW_TIMEOUT 10000
|
||||
|
||||
|
||||
void SAADC_IRQHandler(void)
|
||||
{
|
||||
if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
|
||||
{
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
|
||||
#ifdef NRF52_PAN_28
|
||||
if (m_cb.active_channels == 1)
|
||||
{
|
||||
#endif
|
||||
nrf_drv_saadc_evt_t evt;
|
||||
evt.type = NRF_DRV_SAADC_EVT_DONE;
|
||||
evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer;
|
||||
evt.data.done.size = nrf_saadc_amount_get();
|
||||
|
||||
if (m_cb.p_secondary_buffer == NULL)
|
||||
{
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cb.p_buffer = m_cb.p_secondary_buffer;
|
||||
m_cb.buffer_size = m_cb.secondary_buffer_size;
|
||||
m_cb.p_secondary_buffer = NULL;
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
|
||||
}
|
||||
|
||||
m_cb.event_handler(&evt);
|
||||
#ifdef NRF52_PAN_28
|
||||
}
|
||||
else
|
||||
{
|
||||
//PAN-28: scan mode is not working correctly, emulated by interrupts
|
||||
++(m_cb.buffer_pos);
|
||||
uint16_t buffer_pos = m_cb.buffer_pos;
|
||||
if (buffer_pos == m_cb.buffer_size)
|
||||
{
|
||||
nrf_drv_saadc_evt_t evt;
|
||||
evt.type = NRF_DRV_SAADC_EVT_DONE;
|
||||
evt.data.done.p_buffer = (nrf_saadc_value_t *)(m_cb.p_buffer);
|
||||
evt.data.done.size = m_cb.buffer_size;
|
||||
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
if (m_cb.p_secondary_buffer == NULL)
|
||||
{
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *)m_cb.p_secondary_buffer, (uint16_t)m_cb.secondary_buffer_size);
|
||||
}
|
||||
m_cb.event_handler(&evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t current_scan_pos = m_cb.scan_pos;
|
||||
|
||||
nrf_saadc_channel_input_set(current_scan_pos,
|
||||
NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
|
||||
|
||||
nrf_saadc_buffer_init((nrf_saadc_value_t *)(m_cb.p_buffer + m_cb.buffer_pos), 1);
|
||||
// Find the next enabled channel.
|
||||
for (++m_cb.scan_pos; m_cb.scan_pos < NRF_SAADC_CHANNEL_COUNT; ++m_cb.scan_pos)
|
||||
{
|
||||
if (m_cb.psel[m_cb.scan_pos].pselp)
|
||||
{
|
||||
nrf_saadc_channel_input_set(m_cb.scan_pos,
|
||||
m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//if scanning is done prepare for next round.
|
||||
for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i)
|
||||
{
|
||||
if (m_cb.psel[i].pselp)
|
||||
{
|
||||
m_cb.scan_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nrf_saadc_channel_input_set(m_cb.scan_pos,
|
||||
m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED))
|
||||
{
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t limit_flags = m_cb.limits_enabled_flags;
|
||||
uint32_t flag_idx;
|
||||
nrf_saadc_event_t event;
|
||||
while (limit_flags)
|
||||
{
|
||||
flag_idx = __CLZ(limit_flags);
|
||||
limit_flags &= ~((1UL<<31) >> flag_idx);
|
||||
event = FLAG_IDX_TO_EVENT(flag_idx);
|
||||
if (nrf_saadc_event_check(event))
|
||||
{
|
||||
nrf_saadc_event_clear(event);
|
||||
nrf_drv_saadc_evt_t evt;
|
||||
evt.type = NRF_DRV_SAADC_EVT_LIMIT;
|
||||
evt.data.limit.channel = LIMIT_EVENT_TO_CHANNEL(event);
|
||||
evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event);
|
||||
m_cb.event_handler(&evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config,
|
||||
nrf_drv_saadc_event_handler_t event_handler)
|
||||
{
|
||||
if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
if (event_handler == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (p_config == NULL)
|
||||
{
|
||||
p_config = &m_default_config;
|
||||
}
|
||||
|
||||
m_cb.event_handler = event_handler;
|
||||
nrf_saadc_resolution_set(p_config->resolution);
|
||||
nrf_saadc_oversample_set(p_config->oversample);
|
||||
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
m_cb.active_channels = 0;
|
||||
m_cb.limits_enabled_flags = 0;
|
||||
#ifdef NRF52_PAN_28
|
||||
m_cb.buffer_pos = 0;
|
||||
#endif
|
||||
|
||||
nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
|
||||
nrf_drv_common_irq_enable(SAADC_IRQn, p_config->interrupt_priority);
|
||||
nrf_saadc_int_enable(NRF_SAADC_INT_END);
|
||||
|
||||
nrf_saadc_enable();
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void nrf_drv_saadc_uninit(void)
|
||||
{
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
nrf_drv_common_irq_disable(SAADC_IRQn);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
|
||||
|
||||
// Wait for ADC being stopped.
|
||||
uint32_t timeout = HW_TIMEOUT;
|
||||
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 && timeout > 0)
|
||||
{
|
||||
--timeout;
|
||||
}
|
||||
ASSERT(timeout > 0);
|
||||
|
||||
nrf_saadc_disable();
|
||||
nrf_saadc_int_disable(NRF_SAADC_INT_ALL);
|
||||
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
|
||||
for (uint8_t channel = 0; channel < NRF_SAADC_CHANNEL_COUNT; ++channel)
|
||||
{
|
||||
if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED)
|
||||
{
|
||||
(void)nrf_drv_saadc_channel_uninit(channel);
|
||||
}
|
||||
}
|
||||
|
||||
m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_drv_saadc_channel_init(uint8_t channel,
|
||||
nrf_saadc_channel_config_t const * const p_config)
|
||||
{
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
|
||||
//Oversampling can be used only with one channel.
|
||||
ASSERT((nrf_saadc_oversample_get()==NRF_SAADC_OVERSAMPLE_DISABLED) || (m_cb.active_channels == 0));
|
||||
ASSERT((p_config->pin_p <= NRF_SAADC_INPUT_VDD) && (p_config->pin_p > NRF_SAADC_INPUT_DISABLED));
|
||||
ASSERT(p_config->pin_n <= NRF_SAADC_INPUT_VDD);
|
||||
|
||||
// A channel can only be initialized if the driver is in the idle state.
|
||||
if (m_cb.adc_state == NRF_SAADC_STATE_BUSY)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (!m_cb.psel[channel].pselp)
|
||||
{
|
||||
++m_cb.active_channels;
|
||||
}
|
||||
m_cb.psel[channel].pselp = p_config->pin_p;
|
||||
m_cb.psel[channel].pseln = p_config->pin_n;
|
||||
nrf_saadc_channel_init(channel, p_config);
|
||||
|
||||
#ifdef NRF52_PAN_28
|
||||
nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
|
||||
#else
|
||||
nrf_saadc_channel_input_set(channel, p_config->pin_p, p_config->pin_n);
|
||||
#endif
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel)
|
||||
{
|
||||
ASSERT(channel <= NRF_SAADC_CHANNEL_COUNT)
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
|
||||
// A channel can only be uninitialized if the driver is in the idle state.
|
||||
if (m_cb.adc_state == NRF_SAADC_STATE_BUSY)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (m_cb.psel[channel].pselp)
|
||||
{
|
||||
--m_cb.active_channels;
|
||||
}
|
||||
m_cb.psel[channel].pselp = NRF_SAADC_INPUT_DISABLED;
|
||||
m_cb.psel[channel].pseln = NRF_SAADC_INPUT_DISABLED;
|
||||
nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
|
||||
nrf_drv_saadc_limits_set(channel, NRF_DRV_SAADC_LIMITL_DISABLED, NRF_DRV_SAADC_LIMITH_DISABLED);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value)
|
||||
{
|
||||
if (m_cb.adc_state != NRF_SAADC_STATE_IDLE)
|
||||
{
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
m_cb.adc_state = NRF_SAADC_STATE_BUSY;
|
||||
nrf_saadc_int_disable(NRF_SAADC_INT_END);
|
||||
nrf_saadc_buffer_init(p_value, 1);
|
||||
#ifndef NRF52_PAN_28
|
||||
if (m_cb.active_channels > 1)
|
||||
{
|
||||
for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i)
|
||||
{
|
||||
nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nrf_saadc_channel_input_set(channel,
|
||||
m_cb.psel[channel].pselp, m_cb.psel[channel].pseln);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
|
||||
|
||||
uint32_t timeout = HW_TIMEOUT;
|
||||
while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) && timeout > 0)
|
||||
{
|
||||
timeout--;
|
||||
}
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
|
||||
|
||||
#ifdef NRF52_PAN_28
|
||||
nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);
|
||||
#else
|
||||
if (m_cb.active_channels > 1)
|
||||
{
|
||||
for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i)
|
||||
{
|
||||
nrf_saadc_channel_input_set(i, m_cb.psel[i].pselp, m_cb.psel[i].pseln);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nrf_saadc_int_enable(NRF_SAADC_INT_END);
|
||||
m_cb.adc_state = NRF_SAADC_STATE_IDLE;
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t size)
|
||||
{
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
|
||||
nrf_saadc_int_disable(NRF_SAADC_INT_END);
|
||||
if (m_cb.adc_state == NRF_SAADC_STATE_BUSY)
|
||||
{
|
||||
if ( m_cb.p_secondary_buffer)
|
||||
{
|
||||
nrf_saadc_int_enable(NRF_SAADC_INT_END);
|
||||
return NRF_ERROR_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cb.p_secondary_buffer = p_buffer;
|
||||
m_cb.secondary_buffer_size = size;
|
||||
#ifdef NRF52_PAN_28
|
||||
if (m_cb.active_channels == 1)
|
||||
#endif
|
||||
{
|
||||
while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0);
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
|
||||
nrf_saadc_buffer_init(p_buffer, size);
|
||||
}
|
||||
nrf_saadc_int_enable(NRF_SAADC_INT_END);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
}
|
||||
nrf_saadc_int_enable(NRF_SAADC_INT_END);
|
||||
m_cb.adc_state = NRF_SAADC_STATE_BUSY;
|
||||
|
||||
#ifdef NRF52_PAN_28
|
||||
m_cb.scan_pos = NRF_SAADC_CHANNEL_COUNT;
|
||||
for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i)
|
||||
{
|
||||
if (m_cb.psel[i].pselp)
|
||||
{
|
||||
m_cb.scan_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the first enabled channel.
|
||||
if (m_cb.scan_pos >= NRF_SAADC_CHANNEL_COUNT)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
m_cb.buffer_pos = 0;
|
||||
#endif
|
||||
m_cb.p_buffer = p_buffer;
|
||||
m_cb.buffer_size = size;
|
||||
m_cb.p_secondary_buffer = NULL;
|
||||
|
||||
#ifdef NRF52_PAN_28
|
||||
nrf_saadc_channel_input_set(m_cb.scan_pos,
|
||||
m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln);
|
||||
|
||||
if (m_cb.active_channels == 1)
|
||||
{
|
||||
nrf_saadc_buffer_init(p_buffer, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_saadc_buffer_init(p_buffer, 1);
|
||||
}
|
||||
#else
|
||||
nrf_saadc_buffer_init(p_buffer, size);
|
||||
#endif
|
||||
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf_drv_saadc_sample()
|
||||
{
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
if (m_cb.adc_state == NRF_SAADC_STATE_IDLE)
|
||||
{
|
||||
err_code = NRF_ERROR_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
bool nrf_drv_saadc_is_busy(void)
|
||||
{
|
||||
return (m_cb.adc_state == NRF_SAADC_STATE_BUSY);
|
||||
}
|
||||
|
||||
void nrf_drv_saadc_abort(void)
|
||||
{
|
||||
if (nrf_drv_saadc_is_busy())
|
||||
{
|
||||
nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
|
||||
nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
|
||||
|
||||
// Wait for ADC being stopped.
|
||||
uint32_t timeout = HW_TIMEOUT;
|
||||
while ((m_cb.adc_state != NRF_SAADC_STATE_IDLE) && (timeout > 0))
|
||||
{
|
||||
--timeout;
|
||||
}
|
||||
ASSERT(timeout > 0);
|
||||
|
||||
m_cb.p_buffer = 0;
|
||||
m_cb.p_secondary_buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high)
|
||||
{
|
||||
ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
ASSERT(m_cb.event_handler); // only non blocking mode supported
|
||||
ASSERT(limit_low>=NRF_DRV_SAADC_LIMITL_DISABLED);
|
||||
ASSERT(limit_high<=NRF_DRV_SAADC_LIMITH_DISABLED);
|
||||
ASSERT(limit_low<limit_high);
|
||||
nrf_saadc_channel_limits_set(channel, limit_low, limit_high);
|
||||
|
||||
uint32_t int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_LOW);
|
||||
if (limit_low == NRF_DRV_SAADC_LIMITL_DISABLED)
|
||||
{
|
||||
m_cb.limits_enabled_flags &= ~(0x80000000 >> LOW_LIMIT_TO_FLAG(channel));
|
||||
nrf_saadc_int_disable(int_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cb.limits_enabled_flags |= (0x80000000 >> LOW_LIMIT_TO_FLAG(channel));
|
||||
nrf_saadc_int_enable(int_mask);
|
||||
}
|
||||
|
||||
int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_HIGH);
|
||||
if (limit_high == NRF_DRV_SAADC_LIMITH_DISABLED)
|
||||
{
|
||||
m_cb.limits_enabled_flags &= ~(0x80000000 >> HIGH_LIMIT_TO_FLAG(channel));
|
||||
nrf_saadc_int_disable(int_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cb.limits_enabled_flags |= (0x80000000 >> HIGH_LIMIT_TO_FLAG(channel));
|
||||
nrf_saadc_int_enable(int_mask);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup nrf_saadc SAADC HAL and driver
|
||||
* @ingroup nrf_drivers
|
||||
* @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) APIs.
|
||||
* @details The SAADC HAL provides basic APIs for accessing the registers of the SAADC peripheral.
|
||||
* The SAADC driver provides APIs on a higher level.
|
||||
*
|
||||
* @defgroup nrf_drv_saadc SAADC driver
|
||||
* @{
|
||||
* @ingroup nrf_saadc
|
||||
*
|
||||
* @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) driver.
|
||||
*/
|
||||
|
||||
#ifndef NRF_DRV_SAADC_H__
|
||||
#define NRF_DRV_SAADC_H__
|
||||
|
||||
#include "nrf_drv_config.h"
|
||||
#include "nrf_saadc.h"
|
||||
#include "sdk_errors.h"
|
||||
|
||||
/**
|
||||
* @brief Value that should be set as high limit to disable limit detection.
|
||||
*/
|
||||
#define NRF_DRV_SAADC_LIMITH_DISABLED (2047)
|
||||
/**
|
||||
* @brief Value that should be set as low limit to disable limit detection.
|
||||
*/
|
||||
#define NRF_DRV_SAADC_LIMITL_DISABLED (-2048)
|
||||
|
||||
/**
|
||||
* @brief Macro for setting @ref nrf_drv_saadc_config_t to default settings.
|
||||
*/
|
||||
#define NRF_DRV_SAADC_DEFAULT_CONFIG \
|
||||
{ \
|
||||
.resolution = SAADC_CONFIG_RESOLUTION, \
|
||||
.oversample = SAADC_CONFIG_OVERSAMPLE, \
|
||||
.interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
|
||||
* in single ended mode.
|
||||
*
|
||||
* @param PIN_P Analog input.
|
||||
*/
|
||||
#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \
|
||||
{ \
|
||||
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
|
||||
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
|
||||
.gain = NRF_SAADC_GAIN1_6, \
|
||||
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
|
||||
.acq_time = NRF_SAADC_ACQTIME_10US, \
|
||||
.mode = NRF_SAADC_MODE_SINGLE_ENDED, \
|
||||
.pin_p = (nrf_saadc_input_t)(PIN_P), \
|
||||
.pin_n = NRF_SAADC_INPUT_DISABLED \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings
|
||||
* in differential mode.
|
||||
*
|
||||
* @param PIN_P Positive analog input.
|
||||
* @param PIN_N Negative analog input.
|
||||
*/
|
||||
#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \
|
||||
{ \
|
||||
.resistor_p = NRF_SAADC_RESISTOR_DISABLED, \
|
||||
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, \
|
||||
.gain = NRF_SAADC_GAIN1_6, \
|
||||
.reference = NRF_SAADC_REFERENCE_INTERNAL, \
|
||||
.acq_time = NRF_SAADC_ACQTIME_10US, \
|
||||
.mode = NRF_SAADC_MODE_DIFFERENTIAL, \
|
||||
.pin_p = (nrf_saadc_input_t)(PIN_P), \
|
||||
.pin_n = (nrf_saadc_input_t)(PIN_N) \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter driver configuration structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_saadc_resolution_t resolution; ///< Resolution configuration.
|
||||
nrf_saadc_oversample_t oversample; ///< Oversampling configuration.
|
||||
uint8_t interrupt_priority; ///< Interrupt priority.
|
||||
} nrf_drv_saadc_config_t;
|
||||
|
||||
/**
|
||||
* @brief Driver event types.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
|
||||
NRF_DRV_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached.
|
||||
} nrf_drv_saadc_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter driver done event data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples.
|
||||
uint16_t size; ///< Number of samples in the buffer.
|
||||
} nrf_drv_saadc_done_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter driver limit event data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t channel; ///< Channel on which the limit was detected.
|
||||
nrf_saadc_limit_t limit_type; ///< Type of limit detected.
|
||||
} nrf_drv_saadc_limit_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter driver event structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_saadc_evt_type_t type; ///< Event type.
|
||||
union
|
||||
{
|
||||
nrf_drv_saadc_done_evt_t done; ///< Data for @ref NRF_DRV_SAADC_EVT_DONE event.
|
||||
nrf_drv_saadc_limit_evt_t limit;///< Data for @ref NRF_DRV_SAADC_EVT_LIMIT event.
|
||||
} data;
|
||||
} nrf_drv_saadc_evt_t;
|
||||
|
||||
/**
|
||||
* @brief ADC event handler.
|
||||
*
|
||||
* @param[in] p_event Pointer to an ADC event. The event structure is allocated on
|
||||
* the stack, so it is valid only within the context of
|
||||
* the event handler.
|
||||
*/
|
||||
typedef void (*nrf_drv_saadc_event_handler_t)(nrf_drv_saadc_evt_t const * p_event);
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the SAADC.
|
||||
*
|
||||
* @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used.
|
||||
* @param[in] event_handler Event handler provided by the user.
|
||||
*
|
||||
* @retval NRF_SUCCESS If initialization was successful.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the driver is already initialized.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If event_handler is NULL.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config,
|
||||
nrf_drv_saadc_event_handler_t event_handler);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing the SAADC.
|
||||
*
|
||||
* This function stops all ongoing conversions and disables all channels.
|
||||
*/
|
||||
void nrf_drv_saadc_uninit(void);
|
||||
|
||||
/**
|
||||
* @brief Function for getting the address of a SAMPLE SAADC task.
|
||||
*
|
||||
* @return Task address.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_drv_saadc_sample_task_get(void)
|
||||
{
|
||||
return nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for initializing an SAADC channel.
|
||||
*
|
||||
* This function configures and enables the channel.
|
||||
*
|
||||
* @retval NRF_SUCCESS If initialization was successful.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the ADC was not initialized.
|
||||
* @retval NRF_ERROR_NO_MEM If the specified channel was already allocated.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_channel_init(uint8_t channel,
|
||||
nrf_saadc_channel_config_t const * const p_config);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing an SAADC channel.
|
||||
*
|
||||
* @retval NRF_SUCCESS If uninitialization was successful.
|
||||
* @retval NRF_ERROR_BUSY If the ADC is busy.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel);
|
||||
|
||||
/**
|
||||
* @brief Function for starting SAADC sampling.
|
||||
*
|
||||
* @retval NRF_SUCCESS If ADC sampling was triggered.
|
||||
* @retval NRF_ERROR_BUSY If ADC is in idle state.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_sample(void);
|
||||
|
||||
/**
|
||||
* @brief Blocking function for executing a single ADC conversion.
|
||||
*
|
||||
* This function selects the desired input, starts a single conversion,
|
||||
* waits for it to finish, and returns the result.
|
||||
*
|
||||
* The function will fail if ADC is busy.
|
||||
*
|
||||
* @param[in] channel Channel.
|
||||
* @param[out] p_value Pointer to the location where the result should be placed.
|
||||
*
|
||||
* @retval NRF_SUCCESS If conversion was successful.
|
||||
* @retval NRF_ERROR_BUSY If the ADC driver is busy.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value);
|
||||
|
||||
/**
|
||||
* @brief Function for issuing conversion of data to the buffer.
|
||||
*
|
||||
* This function is non-blocking. The application is notified about filling the buffer by the event handler.
|
||||
* Conversion will be done on all enabled channels. If the ADC is in idle state, the function will set up Easy
|
||||
* DMA for the conversion. The ADC will be ready for sampling and wait for the SAMPLE task. It can be
|
||||
* triggered manually by the @ref nrf_drv_saadc_sample function or by PPI using the @ref NRF_SAADC_TASK_SAMPLE
|
||||
* task. If one buffer is already set and the conversion is ongoing, calling this function will
|
||||
* result in queuing the given buffer. The driver will start filling the issued buffer when the first one is
|
||||
* completed. If the function is called again before the first buffer is filled, it will return with error.
|
||||
*
|
||||
* @param[in] buffer Result buffer.
|
||||
* @param[in] size Buffer size in words.
|
||||
*
|
||||
* @retval NRF_SUCCESS If conversion was successful.
|
||||
* @retval NRF_ERROR_BUSY If the driver already has two buffers set.
|
||||
*/
|
||||
ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the SAADC state.
|
||||
*
|
||||
* @retval true If the ADC is busy.
|
||||
* @retval false If the ADC is ready.
|
||||
*/
|
||||
bool nrf_drv_saadc_is_busy(void);
|
||||
|
||||
/**
|
||||
* @brief Function for aborting ongoing and buffered conversions.
|
||||
* @note @ref NRF_DRV_SAADC_EVT_DONE event will be generated if there is a conversion in progress.
|
||||
* Event will contain number of words in the sample buffer.
|
||||
*/
|
||||
void nrf_drv_saadc_abort(void);
|
||||
|
||||
/**
|
||||
* @brief Function for setting the SAADC channel limits.
|
||||
* When limits are enabled and the result exceeds the defined bounds, the limit handler function is called.
|
||||
*
|
||||
* @param[in] channel SAADC channel number.
|
||||
* @param[in] limit_low Lower limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to
|
||||
* @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results below this value will trigger
|
||||
* the handler function. Set to @ref NRF_DRV_SAADC_LIMITL_DISABLED to disable this limit.
|
||||
* @param[in] limit_high Upper limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to
|
||||
* @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results above this value will trigger
|
||||
* the handler function. Set to @ref NRF_DRV_SAADC_LIMITH_DISABLED to disable this limit.
|
||||
*/
|
||||
void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high);
|
||||
|
||||
/**
|
||||
* @brief Function for converting a GPIO pin number to an analog input pin number used in the channel
|
||||
* configuration.
|
||||
*
|
||||
* @param[in] pin GPIO pin.
|
||||
*
|
||||
* @return Value representing an analog input pin. The function returns @ref NRF_SAADC_INPUT_DISABLED
|
||||
* if the specified pin is not an analog input.
|
||||
*/
|
||||
__STATIC_INLINE nrf_saadc_input_t nrf_drv_saadc_gpio_to_ain(uint32_t pin)
|
||||
{
|
||||
// AIN0 - AIN3
|
||||
if (pin >= 2 && pin <= 5)
|
||||
{
|
||||
//0 means "not connected", hence this "+ 1"
|
||||
return (nrf_saadc_input_t)(pin - 2 + 1);
|
||||
}
|
||||
// AIN4 - AIN7
|
||||
else if (pin >= 28 && pin <= 31)
|
||||
{
|
||||
return (nrf_saadc_input_t)(pin - 24 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_SAADC_INPUT_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NRF_DRV_SAADC_H__
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,35 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef NRF52
|
||||
/**
|
||||
* @file
|
||||
* @brief SAADC HAL implementation
|
||||
*/
|
||||
|
||||
#include "nrf_saadc.h"
|
||||
|
||||
void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config)
|
||||
{
|
||||
NRF_SAADC->CH[channel].CONFIG =
|
||||
((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk)
|
||||
| ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk)
|
||||
| ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk)
|
||||
| ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk)
|
||||
| ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk)
|
||||
| ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk);
|
||||
nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif //NRF52
|
||||
|
|
@ -0,0 +1,560 @@
|
|||
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
|
||||
*
|
||||
* The information contained herein is property of Nordic Semiconductor ASA.
|
||||
* Terms and conditions of usage are described in detail in NORDIC
|
||||
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information. NO
|
||||
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
|
||||
* the file.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NRF_SAADC_H_
|
||||
#define NRF_SAADC_H_
|
||||
|
||||
#ifdef NRF52
|
||||
|
||||
/**
|
||||
* @defgroup nrf_saadc_hal SAADC HAL
|
||||
* @{
|
||||
* @ingroup nrf_saadc
|
||||
*
|
||||
* @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
|
||||
|
||||
#define NRF_SAADC_CHANNEL_COUNT 8
|
||||
|
||||
/**
|
||||
* @brief Resolution of the analog-to-digital converter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_RESOLUTION_8BIT = SAADC_RESOLUTION_VAL_8bit, ///< 8 bit resolution.
|
||||
NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///< 10 bit resolution.
|
||||
NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///< 12 bit resolution.
|
||||
NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit ///< 14 bit resolution.
|
||||
} nrf_saadc_resolution_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Input selection for the analog-to-digital converter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC, ///< Not connected.
|
||||
NRF_SAADC_INPUT_AIN0 = SAADC_CH_PSELP_PSELP_AnalogInput0, ///< Analog input 0 (AIN0).
|
||||
NRF_SAADC_INPUT_AIN1 = SAADC_CH_PSELP_PSELP_AnalogInput1, ///< Analog input 1 (AIN1).
|
||||
NRF_SAADC_INPUT_AIN2 = SAADC_CH_PSELP_PSELP_AnalogInput2, ///< Analog input 2 (AIN2).
|
||||
NRF_SAADC_INPUT_AIN3 = SAADC_CH_PSELP_PSELP_AnalogInput3, ///< Analog input 3 (AIN3).
|
||||
NRF_SAADC_INPUT_AIN4 = SAADC_CH_PSELP_PSELP_AnalogInput4, ///< Analog input 4 (AIN4).
|
||||
NRF_SAADC_INPUT_AIN5 = SAADC_CH_PSELP_PSELP_AnalogInput5, ///< Analog input 5 (AIN5).
|
||||
NRF_SAADC_INPUT_AIN6 = SAADC_CH_PSELP_PSELP_AnalogInput6, ///< Analog input 6 (AIN6).
|
||||
NRF_SAADC_INPUT_AIN7 = SAADC_CH_PSELP_PSELP_AnalogInput7, ///< Analog input 7 (AIN7).
|
||||
NRF_SAADC_INPUT_VDD = SAADC_CH_PSELP_PSELP_VDD ///< VDD as input.
|
||||
} nrf_saadc_input_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter oversampling mode.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass, ///< No oversampling.
|
||||
NRF_SAADC_OVERSAMPLE_2X = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, ///< Oversample 2x.
|
||||
NRF_SAADC_OVERSAMPLE_4X = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x, ///< Oversample 4x.
|
||||
NRF_SAADC_OVERSAMPLE_8X = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x, ///< Oversample 8x.
|
||||
NRF_SAADC_OVERSAMPLE_16X = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x, ///< Oversample 16x.
|
||||
NRF_SAADC_OVERSAMPLE_32X = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x, ///< Oversample 32x.
|
||||
NRF_SAADC_OVERSAMPLE_64X = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x, ///< Oversample 64x.
|
||||
NRF_SAADC_OVERSAMPLE_128X = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///< Oversample 128x.
|
||||
NRF_SAADC_OVERSAMPLE_256X = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x ///< Oversample 256x.
|
||||
} nrf_saadc_oversample_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter channel resistor control.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass, ///< Bypass resistor ladder.
|
||||
NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///< Pull-down to GND.
|
||||
NRF_SAADC_RESISTOR_PULLUP = SAADC_CH_CONFIG_RESP_Pullup, ///< Pull-up to VDD.
|
||||
NRF_SAADC_RESISTOR_VDD1_2 = SAADC_CH_CONFIG_RESP_VDD1_2 ///< Set input at VDD/2.
|
||||
} nrf_saadc_resistor_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gain factor of the analog-to-digital converter input.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///< Gain factor 1/6.
|
||||
NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///< Gain factor 1/5.
|
||||
NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///< Gain factor 1/4.
|
||||
NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///< Gain factor 1/3.
|
||||
NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///< Gain factor 1/2.
|
||||
NRF_SAADC_GAIN1 = SAADC_CH_CONFIG_GAIN_Gain1, ///< Gain factor 1.
|
||||
NRF_SAADC_GAIN2 = SAADC_CH_CONFIG_GAIN_Gain2, ///< Gain factor 2.
|
||||
NRF_SAADC_GAIN4 = SAADC_CH_CONFIG_GAIN_Gain4, ///< Gain factor 4.
|
||||
} nrf_saadc_gain_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reference selection for the analog-to-digital converter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///< Internal reference (0.6 V).
|
||||
NRF_SAADC_REFERENCE_VDD4 = SAADC_CH_CONFIG_REFSEL_VDD1_4 ///< VDD/4 as reference.
|
||||
} nrf_saadc_reference_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter acquisition time.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_ACQTIME_3US = SAADC_CH_CONFIG_TACQ_3us, ///< 3 us.
|
||||
NRF_SAADC_ACQTIME_5US = SAADC_CH_CONFIG_TACQ_5us, ///< 5 us.
|
||||
NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///< 10 us.
|
||||
NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///< 15 us.
|
||||
NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///< 20 us.
|
||||
NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us ///< 40 us.
|
||||
} nrf_saadc_acqtime_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter channel mode.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE, ///< Single ended, PSELN will be ignored, negative input to ADC shorted to GND.
|
||||
NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///< Differential mode.
|
||||
} nrf_saadc_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter tasks.
|
||||
*/
|
||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
||||
{
|
||||
NRF_SAADC_TASK_START = offsetof(NRF_SAADC_Type, TASKS_START), ///< Start the ADC and prepare the result buffer in RAM.
|
||||
NRF_SAADC_TASK_SAMPLE = offsetof(NRF_SAADC_Type, TASKS_SAMPLE), ///< Take one ADC sample. If scan is enabled, all channels are sampled.
|
||||
NRF_SAADC_TASK_STOP = offsetof(NRF_SAADC_Type, TASKS_STOP), ///< Stop the ADC and terminate any on-going conversion.
|
||||
NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration.
|
||||
} nrf_saadc_task_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter events.
|
||||
*/
|
||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
||||
{
|
||||
NRF_SAADC_EVENT_STARTED = offsetof(NRF_SAADC_Type, EVENTS_STARTED), ///< The ADC has started.
|
||||
NRF_SAADC_EVENT_END = offsetof(NRF_SAADC_Type, EVENTS_END), ///< The ADC has filled up the result buffer.
|
||||
NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete.
|
||||
NRF_SAADC_EVENT_STOPPED = offsetof(NRF_SAADC_Type, EVENTS_STOPPED), ///< The ADC has stopped.
|
||||
NRF_SAADC_EVENT_CH0_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH), ///< Last result is equal or above CH[0].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH0_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL), ///< Last result is equal or below CH[0].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH1_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH), ///< Last result is equal or above CH[1].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH1_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL), ///< Last result is equal or below CH[1].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH2_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH), ///< Last result is equal or above CH[2].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH2_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL), ///< Last result is equal or below CH[2].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH3_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH), ///< Last result is equal or above CH[3].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH3_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL), ///< Last result is equal or below CH[3].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH4_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH), ///< Last result is equal or above CH[4].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH4_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL), ///< Last result is equal or below CH[4].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH5_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH), ///< Last result is equal or above CH[5].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH5_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL), ///< Last result is equal or below CH[5].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH6_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH), ///< Last result is equal or above CH[6].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH6_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL), ///< Last result is equal or below CH[6].LIMIT.LOW.
|
||||
NRF_SAADC_EVENT_CH7_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH), ///< Last result is equal or above CH[7].LIMIT.HIGH.
|
||||
NRF_SAADC_EVENT_CH7_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL) ///< Last result is equal or below CH[7].LIMIT.LOW.
|
||||
} nrf_saadc_event_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter interrupt masks.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
|
||||
NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event.
|
||||
NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
|
||||
NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event.
|
||||
NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event.
|
||||
NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event.
|
||||
NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event.
|
||||
NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event.
|
||||
NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event.
|
||||
NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event.
|
||||
NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event.
|
||||
NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event.
|
||||
NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event.
|
||||
NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event.
|
||||
NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event.
|
||||
NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event.
|
||||
NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event.
|
||||
NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event.
|
||||
NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event.
|
||||
NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts.
|
||||
} nrf_saadc_int_mask_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter value limit type.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF_SAADC_LIMIT_LOW = 0,
|
||||
NRF_SAADC_LIMIT_HIGH = 1
|
||||
} nrf_saadc_limit_t;
|
||||
|
||||
|
||||
typedef int16_t nrf_saadc_value_t; ///< Type of a single ADC conversion result.
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter configuration structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_saadc_resolution_t resolution;
|
||||
nrf_saadc_oversample_t oversample;
|
||||
nrf_saadc_value_t * buffer;
|
||||
uint32_t buffer_size;
|
||||
} nrf_saadc_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Analog-to-digital converter channel configuration structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
nrf_saadc_resistor_t resistor_p;
|
||||
nrf_saadc_resistor_t resistor_n;
|
||||
nrf_saadc_gain_t gain;
|
||||
nrf_saadc_reference_t reference;
|
||||
nrf_saadc_acqtime_t acq_time;
|
||||
nrf_saadc_mode_t mode;
|
||||
nrf_saadc_input_t pin_p;
|
||||
nrf_saadc_input_t pin_n;
|
||||
} nrf_saadc_channel_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for triggering a specific SAADC task.
|
||||
*
|
||||
* @param[in] saadc_task SAADC task.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task)
|
||||
{
|
||||
*((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for getting the address of a specific SAADC task register.
|
||||
*
|
||||
* @param[in] saadc_task SAADC task.
|
||||
*
|
||||
* @return Address of the specified SAADC task.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task)
|
||||
{
|
||||
return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for getting the state of a specific SAADC event.
|
||||
*
|
||||
* @param[in] saadc_event SAADC event.
|
||||
*
|
||||
* @return State of the specified SAADC event.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event)
|
||||
{
|
||||
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for clearing the specific SAADC event.
|
||||
*
|
||||
* @param[in] saadc_event SAADC event.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event)
|
||||
{
|
||||
*((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for getting the address of a specific SAADC event register.
|
||||
*
|
||||
* @param[in] saadc_event SAADC event.
|
||||
*
|
||||
* @return Address of the specified SAADC event.
|
||||
*/
|
||||
__STATIC_INLINE volatile uint32_t * nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event)
|
||||
{
|
||||
return (volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for getting the address of a specific SAADC limit event register.
|
||||
*
|
||||
* @param[in] channel Channel number.
|
||||
* @param[in] limit_type Low limit or high limit.
|
||||
*
|
||||
* @return Address of the specified SAADC limit event.
|
||||
*/
|
||||
__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type)
|
||||
{
|
||||
ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
|
||||
if (limit_type == NRF_SAADC_LIMIT_HIGH)
|
||||
{
|
||||
return &NRF_SAADC->EVENTS_CH[channel].LIMITH;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &NRF_SAADC->EVENTS_CH[channel].LIMITL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for getting the SAADC channel monitoring limit events.
|
||||
*
|
||||
* @param[in] channel Channel number.
|
||||
* @param[in] limit_type Low limit or high limit.
|
||||
*/
|
||||
__STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type)
|
||||
{
|
||||
if (limit_type == NRF_SAADC_LIMIT_HIGH)
|
||||
{
|
||||
return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH +
|
||||
(uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH)
|
||||
* (uint32_t) channel );
|
||||
}
|
||||
else
|
||||
{
|
||||
return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL +
|
||||
(uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL)
|
||||
* (uint32_t) channel );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the input pins for a specific SAADC channel.
|
||||
*
|
||||
* @param[in] channel Channel number.
|
||||
* @param[in] pselp Positive input.
|
||||
* @param[in] pseln Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel,
|
||||
nrf_saadc_input_t pselp,
|
||||
nrf_saadc_input_t pseln)
|
||||
{
|
||||
NRF_SAADC->CH[channel].PSELN = pseln;
|
||||
NRF_SAADC->CH[channel].PSELP = pselp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for setting the SAADC channel monitoring limits.
|
||||
*
|
||||
* @param[in] channel Channel number.
|
||||
* @param[in] low Low limit.
|
||||
* @param[in] high High limit.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high)
|
||||
{
|
||||
NRF_SAADC->CH[channel].LIMIT = (
|
||||
(((uint32_t) low << SAADC_CH_LIMIT_LOW_Pos) & SAADC_CH_LIMIT_LOW_Msk)
|
||||
| (((uint32_t) high << SAADC_CH_LIMIT_HIGH_Pos) & SAADC_CH_LIMIT_HIGH_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for enabling specified SAADC interrupts.
|
||||
*
|
||||
* @param[in] saadc_int_mask Interrupt(s) to enable.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask)
|
||||
{
|
||||
NRF_SAADC->INTENSET = saadc_int_mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for retrieving the state of specified SAADC interrupts.
|
||||
*
|
||||
* @param[in] saadc_int_mask Interrupt(s) to check.
|
||||
*
|
||||
* @retval true If all specified interrupts are enabled.
|
||||
* @retval false If at least one of the given interrupts is not enabled.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask)
|
||||
{
|
||||
return (bool)(NRF_SAADC->INTENSET & saadc_int_mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for disabling specified interrupts.
|
||||
*
|
||||
* @param saadc_int_mask Interrupt(s) to disable.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask)
|
||||
{
|
||||
NRF_SAADC->INTENCLR = saadc_int_mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for generating masks for SAADC channel limit interrupts.
|
||||
*
|
||||
* @param[in] channel SAADC channel number.
|
||||
* @param[in] limit_type Limit type.
|
||||
*
|
||||
* @returns Interrupt mask.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type)
|
||||
{
|
||||
ASSERT(channel < NRF_SAADC_CHANNEL_COUNT);
|
||||
uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH;
|
||||
return mask << (channel * 2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for checking whether the SAADC is busy.
|
||||
*
|
||||
* This function checks whether the analog-to-digital converter is busy with a conversion.
|
||||
*
|
||||
* @retval true If the SAADC is busy.
|
||||
* @retval false If the SAADC is not busy.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_saadc_busy_check(void)
|
||||
{
|
||||
//return ((NRF_SAADC->STATUS & SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk);
|
||||
//simplified for performance
|
||||
return NRF_SAADC->STATUS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for enabling the SAADC.
|
||||
*
|
||||
* The analog-to-digital converter must be enabled before use.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_enable(void)
|
||||
{
|
||||
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for disabling the SAADC.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_disable(void)
|
||||
{
|
||||
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for checking if the SAADC is enabled.
|
||||
*
|
||||
* @retval true If the SAADC is enabled.
|
||||
* @retval false If the SAADC is not enabled.
|
||||
*/
|
||||
__STATIC_INLINE bool nrf_saadc_enable_check(void)
|
||||
{
|
||||
//simplified for performance
|
||||
return NRF_SAADC->ENABLE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the SAADC result buffer.
|
||||
*
|
||||
* @param[in] buffer Pointer to the result buffer.
|
||||
* @param[in] num Size of buffer in words.
|
||||
*/
|
||||
__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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for getting the number of buffer words transferred since last START operation.
|
||||
*
|
||||
* @returns Number of words transferred.
|
||||
*/
|
||||
__STATIC_INLINE uint16_t nrf_saadc_amount_get(void)
|
||||
{
|
||||
return NRF_SAADC->RESULT.AMOUNT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for setting the SAADC sample resolution.
|
||||
*
|
||||
* @param[in] resolution Bit resolution.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)
|
||||
{
|
||||
NRF_SAADC->RESOLUTION = resolution;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the oversampling feature.
|
||||
*
|
||||
* @param[in] oversample Oversampling mode.
|
||||
*/
|
||||
__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)
|
||||
{
|
||||
NRF_SAADC->OVERSAMPLE = oversample;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for getting the oversampling feature configuration.
|
||||
*
|
||||
* @return Oversampling configuration.
|
||||
*/
|
||||
__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void)
|
||||
{
|
||||
return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for initializing the SAADC channel.
|
||||
*
|
||||
* @param[in] channel Channel number.
|
||||
* @param[in] config Pointer to the channel configuration structure.
|
||||
*/
|
||||
void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config);
|
||||
|
||||
/**
|
||||
*@}
|
||||
**/
|
||||
|
||||
#endif // NRF52
|
||||
|
||||
#endif /* NRF_SAADC_H_ */
|
Loading…
Reference in New Issue