mirror of https://github.com/ARMmbed/mbed-os.git
Fix AnalogInput fo nRF51.
parent
3bdbccb5c0
commit
a664be0347
|
@ -1375,7 +1375,7 @@
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
"inherits": ["MCU_NRF51_32K"],
|
"inherits": ["MCU_NRF51_32K"],
|
||||||
"progen": {"target": "nrf51-dk"},
|
"progen": {"target": "nrf51-dk"},
|
||||||
"device_has": ["ERROR_PATTERN", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH"]
|
"device_has": ["ANALOGIN", "ERROR_PATTERN", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPI_ASYNCH"]
|
||||||
},
|
},
|
||||||
"NRF51_DK_BOOT": {
|
"NRF51_DK_BOOT": {
|
||||||
"supported_form_factors": ["ARDUINO"],
|
"supported_form_factors": ["ARDUINO"],
|
||||||
|
|
|
@ -12,17 +12,18 @@
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "mbed_assert.h"
|
#include "mbed_assert.h"
|
||||||
#include "analogin_api.h"
|
#include "analogin_api.h"
|
||||||
#include "cmsis.h"
|
#include "cmsis.h"
|
||||||
#include "pinmap.h"
|
#include "pinmap.h"
|
||||||
|
#include "nrf_drv_adc.h"
|
||||||
|
|
||||||
#ifdef DEVICE_ANALOGIN
|
#ifdef DEVICE_ANALOGIN
|
||||||
|
|
||||||
#define ANALOGIN_MEDIAN_FILTER 1
|
|
||||||
#define ADC_10BIT_RANGE 0x3FF
|
#define ADC_10BIT_RANGE 0x3FF
|
||||||
#define ADC_RANGE ADC_10BIT_RANGE
|
#define ADC_RANGE ADC_10BIT_RANGE
|
||||||
|
|
||||||
static const PinMap PinMap_ADC[] = {
|
static const PinMap PinMap_ADC[] = {
|
||||||
{p1, ADC0_0, 4},
|
{p1, ADC0_0, 4},
|
||||||
|
@ -38,47 +39,42 @@ static const PinMap PinMap_ADC[] = {
|
||||||
{NC, NC, 0}
|
{NC, NC, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void analogin_init(analogin_t *obj, PinName pin)
|
void analogin_init(analogin_t *obj, PinName pin)
|
||||||
{
|
{
|
||||||
int analogInputPin = 0;
|
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
|
||||||
const PinMap *map = PinMap_ADC;
|
|
||||||
|
|
||||||
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); //(NRF_ADC_Type *)
|
|
||||||
MBED_ASSERT(obj->adc != (ADCName)NC);
|
MBED_ASSERT(obj->adc != (ADCName)NC);
|
||||||
|
|
||||||
while (map->pin != NC) {
|
uint32_t pinFunc = pinmap_function(pin, PinMap_ADC);
|
||||||
if (map->pin == pin) {
|
MBED_ASSERT(pinFunc != (uint32_t)NC);
|
||||||
analogInputPin = map->function;
|
|
||||||
break;
|
obj->adc_pin = pinFunc;
|
||||||
}
|
|
||||||
map++;
|
ret_code_t ret_code;
|
||||||
}
|
// p_config, event_handler
|
||||||
obj->adc_pin = (uint8_t)analogInputPin;
|
ret_code = nrf_drv_adc_init(NULL , NULL); // select blocking mode
|
||||||
|
MBED_ASSERT(ret_code == NRF_SUCCESS);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t analogin_read_u16(analogin_t *obj)
|
uint16_t analogin_read_u16(analogin_t *obj)
|
||||||
{
|
{
|
||||||
NRF_ADC->CONFIG &= ~ADC_CONFIG_PSEL_Msk;
|
nrf_adc_value_t adc_value = 0xFFFF;
|
||||||
NRF_ADC->CONFIG |= obj->adc_pin << ADC_CONFIG_PSEL_Pos;
|
|
||||||
NRF_ADC->EVENTS_END = 0;
|
nrf_drv_adc_channel_t adc_channel = NRF_DRV_ADC_DEFAULT_CHANNEL(obj->adc_pin);
|
||||||
NRF_ADC->TASKS_START = 1;
|
|
||||||
|
|
||||||
while (!NRF_ADC->EVENTS_END) {
|
ret_code_t ret_code;
|
||||||
}
|
|
||||||
|
ret_code = nrf_drv_adc_sample_convert( &adc_channel, &adc_value);
|
||||||
return (uint16_t)NRF_ADC->RESULT; // 10 bit
|
MBED_ASSERT(ret_code == NRF_SUCCESS);
|
||||||
|
|
||||||
|
return adc_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float analogin_read(analogin_t *obj)
|
float analogin_read(analogin_t *obj)
|
||||||
{
|
{
|
||||||
uint16_t value = analogin_read_u16(obj);
|
uint16_t value = analogin_read_u16(obj);
|
||||||
|
|
||||||
return (float)value * (1.0f / (float)ADC_RANGE);
|
return (float)value * (1.0f / (float)ADC_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
/* 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_adc.h"
|
||||||
|
#include "nrf_drv_common.h"
|
||||||
|
#include "nrf_assert.h"
|
||||||
|
#include "app_util_platform.h"
|
||||||
|
#include "app_util.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
nrf_drv_adc_event_handler_t event_handler;
|
||||||
|
nrf_drv_adc_channel_t * p_head;
|
||||||
|
nrf_drv_adc_channel_t * p_current_conv;
|
||||||
|
nrf_adc_value_t * p_buffer;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t idx;
|
||||||
|
nrf_drv_state_t state;
|
||||||
|
} adc_cb_t;
|
||||||
|
|
||||||
|
static adc_cb_t m_cb;
|
||||||
|
static const nrf_drv_adc_config_t m_default_config = NRF_DRV_ADC_DEFAULT_CONFIG;
|
||||||
|
|
||||||
|
ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config,
|
||||||
|
nrf_drv_adc_event_handler_t event_handler)
|
||||||
|
{
|
||||||
|
if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED)
|
||||||
|
{
|
||||||
|
return NRF_ERROR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf_adc_event_clear(NRF_ADC_EVENT_END);
|
||||||
|
if (event_handler)
|
||||||
|
{
|
||||||
|
if (!p_config)
|
||||||
|
{
|
||||||
|
p_config = (nrf_drv_adc_config_t *)&m_default_config;
|
||||||
|
}
|
||||||
|
nrf_drv_common_irq_enable(ADC_IRQn, p_config->interrupt_priority);
|
||||||
|
}
|
||||||
|
m_cb.event_handler = event_handler;
|
||||||
|
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||||
|
|
||||||
|
return NRF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_drv_adc_uninit(void)
|
||||||
|
{
|
||||||
|
m_cb.p_head = NULL;
|
||||||
|
nrf_drv_common_irq_disable(ADC_IRQn);
|
||||||
|
nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
|
||||||
|
nrf_adc_task_trigger(NRF_ADC_TASK_STOP);
|
||||||
|
|
||||||
|
m_cb.state = NRF_DRV_STATE_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state == NRF_DRV_STATE_INITIALIZED);
|
||||||
|
ASSERT(!is_address_from_stack(p_channel));
|
||||||
|
|
||||||
|
p_channel->p_next = NULL;
|
||||||
|
if (m_cb.p_head == NULL)
|
||||||
|
{
|
||||||
|
m_cb.p_head = p_channel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head;
|
||||||
|
while (p_curr_channel->p_next != NULL)
|
||||||
|
{
|
||||||
|
ASSERT(p_channel != p_curr_channel);
|
||||||
|
p_curr_channel = p_curr_channel->p_next;
|
||||||
|
}
|
||||||
|
p_curr_channel->p_next = p_channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state == NRF_DRV_STATE_INITIALIZED);
|
||||||
|
ASSERT(m_cb.p_head);
|
||||||
|
|
||||||
|
nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head;
|
||||||
|
nrf_drv_adc_channel_t * p_prev_channel = NULL;
|
||||||
|
while(p_curr_channel != p_channel)
|
||||||
|
{
|
||||||
|
p_prev_channel = p_curr_channel;
|
||||||
|
p_curr_channel = p_curr_channel->p_next;
|
||||||
|
ASSERT(p_curr_channel == NULL);
|
||||||
|
}
|
||||||
|
if (p_prev_channel)
|
||||||
|
{
|
||||||
|
p_prev_channel->p_next = p_curr_channel->p_next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cb.p_head = p_curr_channel->p_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nrf_drv_adc_sample(void)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
|
||||||
|
ASSERT(!nrf_adc_is_busy());
|
||||||
|
nrf_adc_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel,
|
||||||
|
nrf_adc_value_t * p_value)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
|
||||||
|
if(m_cb.state == NRF_DRV_STATE_POWERED_ON)
|
||||||
|
{
|
||||||
|
return NRF_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cb.state = NRF_DRV_STATE_POWERED_ON;
|
||||||
|
|
||||||
|
nrf_adc_config_set(p_channel->config.data);
|
||||||
|
nrf_adc_enable();
|
||||||
|
nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
|
||||||
|
nrf_adc_start();
|
||||||
|
if (p_value)
|
||||||
|
{
|
||||||
|
while(!nrf_adc_event_check(NRF_ADC_EVENT_END)) {}
|
||||||
|
nrf_adc_event_clear(NRF_ADC_EVENT_END);
|
||||||
|
*p_value = (nrf_adc_value_t)nrf_adc_result_get();
|
||||||
|
nrf_adc_disable();
|
||||||
|
|
||||||
|
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(m_cb.event_handler);
|
||||||
|
m_cb.p_buffer = NULL;
|
||||||
|
nrf_adc_int_enable(NRF_ADC_INT_END_MASK);
|
||||||
|
}
|
||||||
|
return NRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool adc_sample_process()
|
||||||
|
{
|
||||||
|
nrf_adc_event_clear(NRF_ADC_EVENT_END);
|
||||||
|
nrf_adc_disable();
|
||||||
|
m_cb.p_buffer[m_cb.idx] = (nrf_adc_value_t)nrf_adc_result_get();
|
||||||
|
m_cb.idx++;
|
||||||
|
if (m_cb.idx < m_cb.size)
|
||||||
|
{
|
||||||
|
bool task_trigger = false;
|
||||||
|
if (m_cb.p_current_conv->p_next == NULL)
|
||||||
|
{
|
||||||
|
m_cb.p_current_conv = m_cb.p_head;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cb.p_current_conv = m_cb.p_current_conv->p_next;
|
||||||
|
task_trigger = true;
|
||||||
|
}
|
||||||
|
nrf_adc_config_set(m_cb.p_current_conv->config.data);
|
||||||
|
nrf_adc_enable();
|
||||||
|
if (task_trigger)
|
||||||
|
{
|
||||||
|
//nrf_adc_start();
|
||||||
|
nrf_adc_task_trigger(NRF_ADC_TASK_START);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
|
||||||
|
if(m_cb.state == NRF_DRV_STATE_POWERED_ON)
|
||||||
|
{
|
||||||
|
return NRF_ERROR_BUSY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cb.state = NRF_DRV_STATE_POWERED_ON;
|
||||||
|
m_cb.p_current_conv = m_cb.p_head;
|
||||||
|
m_cb.size = size;
|
||||||
|
m_cb.idx = 0;
|
||||||
|
m_cb.p_buffer = buffer;
|
||||||
|
nrf_adc_config_set(m_cb.p_current_conv->config.data);
|
||||||
|
nrf_adc_event_clear(NRF_ADC_EVENT_END);
|
||||||
|
nrf_adc_enable();
|
||||||
|
if (m_cb.event_handler)
|
||||||
|
{
|
||||||
|
nrf_adc_int_enable(NRF_ADC_INT_END_MASK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
while(!nrf_adc_event_check(NRF_ADC_EVENT_END)){}
|
||||||
|
|
||||||
|
if (adc_sample_process())
|
||||||
|
{
|
||||||
|
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NRF_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_drv_adc_is_busy(void)
|
||||||
|
{
|
||||||
|
ASSERT(mp_state != NRF_DRV_STATE_UNINITIALIZED);
|
||||||
|
return (m_cb.state == NRF_DRV_STATE_POWERED_ON) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADC_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (m_cb.p_buffer == NULL)
|
||||||
|
{
|
||||||
|
nrf_adc_event_clear(NRF_ADC_EVENT_END);
|
||||||
|
nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
|
||||||
|
nrf_adc_disable();
|
||||||
|
nrf_drv_adc_evt_t evt;
|
||||||
|
evt.type = NRF_DRV_ADC_EVT_SAMPLE;
|
||||||
|
evt.data.sample.sample = (nrf_adc_value_t)nrf_adc_result_get();
|
||||||
|
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||||
|
m_cb.event_handler(&evt);
|
||||||
|
}
|
||||||
|
else if (adc_sample_process())
|
||||||
|
{
|
||||||
|
nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
|
||||||
|
nrf_drv_adc_evt_t evt;
|
||||||
|
evt.type = NRF_DRV_ADC_EVT_DONE;
|
||||||
|
evt.data.done.p_buffer = m_cb.p_buffer;
|
||||||
|
evt.data.done.size = m_cb.size;
|
||||||
|
m_cb.state = NRF_DRV_STATE_INITIALIZED;
|
||||||
|
m_cb.event_handler(&evt);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,297 @@
|
||||||
|
/* 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_adc.h"
|
||||||
|
#include "nrf_drv_config.h"
|
||||||
|
#include "sdk_errors.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup nrf_adc ADC HAL and driver
|
||||||
|
* @ingroup nrf_drivers
|
||||||
|
* @brief Analog-to-digital converter (ADC) APIs.
|
||||||
|
* @details The ADC HAL provides basic APIs for accessing the registers of the analog-to-digital converter.
|
||||||
|
* The ADC driver provides APIs on a higher level.
|
||||||
|
*
|
||||||
|
* @defgroup nrf_adc_drv ADC driver
|
||||||
|
* @{
|
||||||
|
* @ingroup nrf_adc
|
||||||
|
* @brief Analog-to-digital converter (ADC) driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Driver event types.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_DRV_ADC_EVT_DONE, ///< Event generated when the buffer is filled with samples.
|
||||||
|
NRF_DRV_ADC_EVT_SAMPLE, ///< Event generated when the requested channel is sampled.
|
||||||
|
} nrf_drv_adc_evt_type_t;
|
||||||
|
|
||||||
|
typedef int16_t nrf_adc_value_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Analog-to-digital converter driver DONE event.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
nrf_adc_value_t * p_buffer; ///< Pointer to buffer with converted samples.
|
||||||
|
uint16_t size; ///< Number of samples in the buffer.
|
||||||
|
} nrf_drv_adc_done_evt_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Analog-to-digital converter driver SAMPLE event.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
nrf_adc_value_t sample; ///< Converted sample.
|
||||||
|
} nrf_drv_adc_sample_evt_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Analog-to-digital converter driver event.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
nrf_drv_adc_evt_type_t type; ///< Event type.
|
||||||
|
union
|
||||||
|
{
|
||||||
|
nrf_drv_adc_done_evt_t done; ///< Data for DONE event.
|
||||||
|
nrf_drv_adc_sample_evt_t sample; ///< Data for SAMPLE event.
|
||||||
|
} data;
|
||||||
|
} nrf_drv_adc_evt_t;
|
||||||
|
|
||||||
|
/**@brief Macro for initializing the ADC channel with the default configuration. */
|
||||||
|
#define NRF_DRV_ADC_DEFAULT_CHANNEL(analog_input) \
|
||||||
|
{{{ \
|
||||||
|
.resolution = NRF_ADC_CONFIG_RES_10BIT, \
|
||||||
|
.input = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \
|
||||||
|
.reference = NRF_ADC_CONFIG_REF_VBG, \
|
||||||
|
.ain = (analog_input) \
|
||||||
|
}}, NULL}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC channel configuration.
|
||||||
|
*
|
||||||
|
* @note The bit fields reflect bit fields in the ADC CONFIG register.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t resolution :2; ///< 8-10 bit resolution.
|
||||||
|
uint32_t input :3; ///< Input selection and scaling.
|
||||||
|
uint32_t reference :2; ///< Reference source.
|
||||||
|
uint32_t reserved :1; ///< Unused bit fields.
|
||||||
|
uint32_t ain :8; ///< Analog input.
|
||||||
|
uint32_t external_reference:2; ///< Eternal reference source.
|
||||||
|
}nrf_drv_adc_channel_config_t;
|
||||||
|
|
||||||
|
// Forward declaration of the nrf_drv_adc_channel_t type.
|
||||||
|
typedef struct nrf_drv_adc_channel_s nrf_drv_adc_channel_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC channel.
|
||||||
|
*
|
||||||
|
* This structure is defined by the user and used by the driver. Therefore, it should
|
||||||
|
* not be defined on the stack as a local variable.
|
||||||
|
*/
|
||||||
|
struct nrf_drv_adc_channel_s
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
nrf_drv_adc_channel_config_t config; ///< Channel configuration.
|
||||||
|
uint32_t data; ///< Raw value.
|
||||||
|
} config;
|
||||||
|
nrf_drv_adc_channel_t * p_next; ///< Pointer to the next enabled channel (for internal use).
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC configuration.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t interrupt_priority; ///< Priority of ADC interrupt.
|
||||||
|
} nrf_drv_adc_config_t;
|
||||||
|
|
||||||
|
/** @brief ADC default configuration. */
|
||||||
|
#define NRF_DRV_ADC_DEFAULT_CONFIG \
|
||||||
|
{ \
|
||||||
|
.interrupt_priority = ADC_CONFIG_IRQ_PRIORITY \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief User event handler prototype.
|
||||||
|
*
|
||||||
|
* This function is called when the requested number of samples has been processed.
|
||||||
|
*
|
||||||
|
* @param p_event Event.
|
||||||
|
*/
|
||||||
|
typedef void (*nrf_drv_adc_event_handler_t)(nrf_drv_adc_evt_t const * p_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for initializing the ADC.
|
||||||
|
*
|
||||||
|
* If a valid event handler is provided, the driver is initialized in non-blocking mode.
|
||||||
|
* If event_handler is NULL, the driver works in blocking mode.
|
||||||
|
*
|
||||||
|
* @param[in] p_config Driver configuration.
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config,
|
||||||
|
nrf_drv_adc_event_handler_t event_handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for uninitializing the ADC.
|
||||||
|
*
|
||||||
|
* This function stops all ongoing conversions and disables all channels.
|
||||||
|
*/
|
||||||
|
void nrf_drv_adc_uninit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for enabling an ADC channel.
|
||||||
|
*
|
||||||
|
* This function configures and enables the channel. When @ref nrf_drv_adc_buffer_convert is
|
||||||
|
* called, all channels that have been enabled with this function are sampled.
|
||||||
|
*
|
||||||
|
* @note The channel instance variable @p p_channel is used by the driver as an item
|
||||||
|
* in a list. Therefore, it cannot be an automatic variable, and an assertion fails if it is
|
||||||
|
* an automatic variable (if asserts are enabled).
|
||||||
|
*/
|
||||||
|
void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for disabling an ADC channel.
|
||||||
|
*/
|
||||||
|
void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for starting ADC sampling.
|
||||||
|
*
|
||||||
|
* This function triggers single ADC sampling. If more than one channel is enabled, the driver
|
||||||
|
* emulates scanning and all channels are sampled in the order they were enabled.
|
||||||
|
*/
|
||||||
|
void nrf_drv_adc_sample(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for executing a single ADC conversion.
|
||||||
|
*
|
||||||
|
* This function selects the desired input and starts a single conversion. If a valid pointer
|
||||||
|
* is provided for the result, the function blocks until the conversion is completed. Otherwise, the
|
||||||
|
* function returns when the conversion is started, and the result is provided in an event (driver
|
||||||
|
* must be initialized in non-blocking mode otherwise an assertion will fail). The function will fail if
|
||||||
|
* ADC is busy. The channel does not need to be enabled to perform a single conversion.
|
||||||
|
*
|
||||||
|
* @param[in] p_channel Channel.
|
||||||
|
* @param[out] p_value Pointer to the location where the result should be placed. Unless NULL is
|
||||||
|
* provided, the function is blocking.
|
||||||
|
*
|
||||||
|
* @retval NRF_SUCCESS If conversion was successful.
|
||||||
|
* @retval NRF_ERROR_BUSY If the ADC driver is busy.
|
||||||
|
*/
|
||||||
|
ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel,
|
||||||
|
nrf_adc_value_t * p_value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for converting data to the buffer.
|
||||||
|
*
|
||||||
|
* If the driver is initialized in non-blocking mode, this function returns when the first conversion
|
||||||
|
* is set up. When the buffer is filled, the application is notified by the event handler. If the
|
||||||
|
* driver is initialized in blocking mode, the function returns when the buffer is filled.
|
||||||
|
*
|
||||||
|
* Conversion is done on all enabled channels, but it is not triggered by this
|
||||||
|
* function. This function will prepare the ADC for sampling and then
|
||||||
|
* wait for the SAMPLE task. Sampling can be triggered manually by the @ref
|
||||||
|
* nrf_drv_adc_sample function or by PPI using the @ref NRF_ADC_TASK_START task.
|
||||||
|
*
|
||||||
|
* @note If more than one channel is enabled, the function emulates scanning, and
|
||||||
|
* a single START task will trigger conversion on all enabled channels. For example:
|
||||||
|
* If 3 channels are enabled and the user requests 6 samples, the completion event
|
||||||
|
* handler will be called after 2 START tasks.
|
||||||
|
* @note The application must adjust the sampling frequency. The maximum frequency
|
||||||
|
* depends on the sampling timer and the maximum latency of the ADC interrupt. If
|
||||||
|
* an interrupt is not handled before the next sampling is triggered, the sample
|
||||||
|
* will be lost.
|
||||||
|
*
|
||||||
|
* @param[in] buffer Result buffer.
|
||||||
|
* @param[in] size Buffer size in samples.
|
||||||
|
*
|
||||||
|
* @retval NRF_SUCCESS If conversion was successful.
|
||||||
|
* @retval NRF_ERROR_BUSY If the driver is busy.
|
||||||
|
*/
|
||||||
|
ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for retrieving the ADC state.
|
||||||
|
*
|
||||||
|
* @retval true If the ADC is busy.
|
||||||
|
* @retval false If the ADC is ready.
|
||||||
|
*/
|
||||||
|
bool nrf_drv_adc_is_busy(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for getting the address of the ADC START task.
|
||||||
|
*
|
||||||
|
* This function is used to get the address of the START task, which can be used to trigger ADC
|
||||||
|
* conversion.
|
||||||
|
*
|
||||||
|
* @return Start task address.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for converting a GPIO pin number to an analog input pin mask to be used in
|
||||||
|
* the ADC channel configuration.
|
||||||
|
*
|
||||||
|
* @param[in] pin GPIO pin.
|
||||||
|
*
|
||||||
|
* @return Analog input pin mask. The function returns @ref NRF_ADC_CONFIG_INPUT_DISABLED
|
||||||
|
* if the specified pin is not an analog input.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE nrf_adc_config_input_t nrf_drv_adc_gpio_to_ain(uint32_t pin);
|
||||||
|
|
||||||
|
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void)
|
||||||
|
{
|
||||||
|
return nrf_adc_task_address_get(NRF_ADC_TASK_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE nrf_adc_config_input_t nrf_drv_adc_gpio_to_ain(uint32_t pin)
|
||||||
|
{
|
||||||
|
// AIN2 - AIN7
|
||||||
|
if (pin >= 1 && pin <= 6)
|
||||||
|
{
|
||||||
|
return (nrf_adc_config_input_t)(1 << (pin+1));
|
||||||
|
}
|
||||||
|
// AIN0 - AIN1
|
||||||
|
else if (pin >= 26 && pin <= 27)
|
||||||
|
{
|
||||||
|
return (nrf_adc_config_input_t)(1 <<(pin - 26));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NRF_ADC_CONFIG_INPUT_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/** @} */
|
|
@ -0,0 +1,78 @@
|
||||||
|
/* Copyright (c) 2014 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief ADC HAL implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nrf_adc.h"
|
||||||
|
|
||||||
|
#ifndef NRF52
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for configuring ADC.
|
||||||
|
*
|
||||||
|
* This function powers on ADC and configures it. ADC is in DISABLE state after configuration,
|
||||||
|
* so it should be enabled before using it.
|
||||||
|
*
|
||||||
|
* @param[in] config Requested configuration.
|
||||||
|
*/
|
||||||
|
void nrf_adc_configure(nrf_adc_config_t * config)
|
||||||
|
{
|
||||||
|
uint32_t config_reg = 0;
|
||||||
|
|
||||||
|
config_reg |= ((uint32_t)config->resolution << ADC_CONFIG_RES_Pos) & ADC_CONFIG_RES_Msk;
|
||||||
|
config_reg |= ((uint32_t)config->scaling << ADC_CONFIG_INPSEL_Pos) & ADC_CONFIG_INPSEL_Msk;
|
||||||
|
config_reg |= ((uint32_t)config->reference << ADC_CONFIG_REFSEL_Pos) & ADC_CONFIG_REFSEL_Msk;
|
||||||
|
|
||||||
|
if (config->reference & ADC_CONFIG_EXTREFSEL_Msk)
|
||||||
|
{
|
||||||
|
config_reg |= config->reference & ADC_CONFIG_EXTREFSEL_Msk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select input */
|
||||||
|
nrf_adc_input_select(NRF_ADC_CONFIG_INPUT_DISABLED);
|
||||||
|
|
||||||
|
/* set new configuration keeping selected input */
|
||||||
|
NRF_ADC->CONFIG = config_reg | (NRF_ADC->CONFIG & ADC_CONFIG_PSEL_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Blocking function for executing single ADC conversion.
|
||||||
|
*
|
||||||
|
* This function selects the desired input, starts a single conversion,
|
||||||
|
* waits for it to finish, and returns the result.
|
||||||
|
* ADC is left in STOP state, the given input is selected.
|
||||||
|
* This function does not check if ADC is initialized and powered.
|
||||||
|
*
|
||||||
|
* @param[in] input Requested input to be selected.
|
||||||
|
*
|
||||||
|
* @return Conversion result
|
||||||
|
*/
|
||||||
|
int32_t nrf_adc_convert_single(nrf_adc_config_input_t input)
|
||||||
|
{
|
||||||
|
int32_t val;
|
||||||
|
|
||||||
|
nrf_adc_input_select(input);
|
||||||
|
nrf_adc_start();
|
||||||
|
|
||||||
|
while (!nrf_adc_conversion_finished())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
nrf_adc_conversion_event_clean();
|
||||||
|
val = nrf_adc_result_get();
|
||||||
|
nrf_adc_stop();
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,416 @@
|
||||||
|
/* Copyright (c) 2014 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_ADC_H_
|
||||||
|
#define NRF_ADC_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup nrf_adc_hal ADC HAL
|
||||||
|
* @{
|
||||||
|
* @ingroup nrf_adc
|
||||||
|
* @brief @tagAPI51 Hardware access layer for managing the analog-to-digital converter (ADC).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "nrf.h"
|
||||||
|
|
||||||
|
#ifndef NRF52
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_config_resolution_t
|
||||||
|
* @brief Resolution of the analog-to-digital converter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ADC interrupts.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_ADC_INT_END_MASK = ADC_INTENSET_END_Msk, /**< ADC interrupt on END event. */
|
||||||
|
} nrf_adc_int_mask_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_ADC_CONFIG_RES_8BIT = ADC_CONFIG_RES_8bit, /**< 8 bit resolution. */
|
||||||
|
NRF_ADC_CONFIG_RES_9BIT = ADC_CONFIG_RES_9bit, /**< 9 bit resolution. */
|
||||||
|
NRF_ADC_CONFIG_RES_10BIT = ADC_CONFIG_RES_10bit, /**< 10 bit resolution. */
|
||||||
|
} nrf_adc_config_resolution_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_config_scaling_t
|
||||||
|
* @brief Scaling factor of the analog-to-digital conversion.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE = ADC_CONFIG_INPSEL_AnalogInputNoPrescaling, /**< Full scale input. */
|
||||||
|
NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling, /**< 2/3 scale input. */
|
||||||
|
NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling, /**< 1/3 scale input. */
|
||||||
|
NRF_ADC_CONFIG_SCALING_SUPPLY_TWO_THIRDS = ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling, /**< 2/3 of supply. */
|
||||||
|
NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD = ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling /**< 1/3 of supply. */
|
||||||
|
} nrf_adc_config_scaling_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_config_reference_t
|
||||||
|
* @brief Reference selection of the analog-to-digital converter.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_ADC_CONFIG_REF_VBG = ADC_CONFIG_REFSEL_VBG, /**< 1.2 V reference. */
|
||||||
|
NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling, /**< 1/2 of power supply. */
|
||||||
|
NRF_ADC_CONFIG_REF_SUPPLY_ONE_THIRD = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling, /**< 1/3 of power supply. */
|
||||||
|
NRF_ADC_CONFIG_REF_EXT_REF0 = ADC_CONFIG_REFSEL_External |
|
||||||
|
ADC_CONFIG_EXTREFSEL_AnalogReference0 <<
|
||||||
|
ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */
|
||||||
|
NRF_ADC_CONFIG_REF_EXT_REF1 = ADC_CONFIG_REFSEL_External |
|
||||||
|
ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */
|
||||||
|
} nrf_adc_config_reference_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_config_input_t
|
||||||
|
* @brief Input selection of the analog-to-digital converter.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NRF_ADC_CONFIG_INPUT_DISABLED = ADC_CONFIG_PSEL_Disabled, /**< No input selected. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_0 = ADC_CONFIG_PSEL_AnalogInput0, /**< Input 0. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_1 = ADC_CONFIG_PSEL_AnalogInput1, /**< Input 1. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_2 = ADC_CONFIG_PSEL_AnalogInput2, /**< Input 2. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_3 = ADC_CONFIG_PSEL_AnalogInput3, /**< Input 3. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_4 = ADC_CONFIG_PSEL_AnalogInput4, /**< Input 4. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_5 = ADC_CONFIG_PSEL_AnalogInput5, /**< Input 5. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_6 = ADC_CONFIG_PSEL_AnalogInput6, /**< Input 6. */
|
||||||
|
NRF_ADC_CONFIG_INPUT_7 = ADC_CONFIG_PSEL_AnalogInput7, /**< Input 7. */
|
||||||
|
} nrf_adc_config_input_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_task_t
|
||||||
|
* @brief Analog-to-digital converter tasks.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/*lint -save -e30*/
|
||||||
|
NRF_ADC_TASK_START = offsetof(NRF_ADC_Type, TASKS_START), /**< ADC start sampling task. */
|
||||||
|
NRF_ADC_TASK_STOP = offsetof(NRF_ADC_Type, TASKS_STOP) /**< ADC stop sampling task. */
|
||||||
|
/*lint -restore*/
|
||||||
|
} nrf_adc_task_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum nrf_adc_event_t
|
||||||
|
* @brief Analog-to-digital converter events.
|
||||||
|
*/
|
||||||
|
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
||||||
|
{
|
||||||
|
/*lint -save -e30*/
|
||||||
|
NRF_ADC_EVENT_END = offsetof(NRF_ADC_Type, EVENTS_END) /**< End of conversion event. */
|
||||||
|
/*lint -restore*/
|
||||||
|
} nrf_adc_event_t;
|
||||||
|
|
||||||
|
/**@brief Analog-to-digital converter configuration. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
nrf_adc_config_resolution_t resolution; /**< ADC resolution. */
|
||||||
|
nrf_adc_config_scaling_t scaling; /**< ADC scaling factor. */
|
||||||
|
nrf_adc_config_reference_t reference; /**< ADC reference. */
|
||||||
|
} nrf_adc_config_t;
|
||||||
|
|
||||||
|
/** Default ADC configuration. */
|
||||||
|
#define NRF_ADC_CONFIG_DEFAULT { NRF_ADC_CONFIG_RES_10BIT, \
|
||||||
|
NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD, \
|
||||||
|
NRF_ADC_CONFIG_REF_VBG }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for configuring ADC.
|
||||||
|
*
|
||||||
|
* This function powers on the analog-to-digital converter and configures it.
|
||||||
|
* After the configuration, the ADC is in DISABLE state and must be
|
||||||
|
* enabled before using it.
|
||||||
|
*
|
||||||
|
* @param[in] config Configuration parameters.
|
||||||
|
*/
|
||||||
|
void nrf_adc_configure(nrf_adc_config_t * config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
||||||
|
* After the input is selected, the analog-to-digital converter
|
||||||
|
* is left in STOP state.
|
||||||
|
* The function does not check if the ADC is initialized and powered.
|
||||||
|
*
|
||||||
|
* @param[in] input Input to be selected.
|
||||||
|
*
|
||||||
|
* @return Conversion result.
|
||||||
|
*/
|
||||||
|
int32_t nrf_adc_convert_single(nrf_adc_config_input_t input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for selecting ADC input.
|
||||||
|
*
|
||||||
|
* This function selects the active input of ADC. Ensure that
|
||||||
|
* the ADC is powered on and in IDLE state before calling this function.
|
||||||
|
*
|
||||||
|
* @param[in] input Input to be selected.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_input_select(nrf_adc_config_input_t input)
|
||||||
|
{
|
||||||
|
NRF_ADC->CONFIG =
|
||||||
|
((uint32_t)input << ADC_CONFIG_PSEL_Pos) | (NRF_ADC->CONFIG & ~ADC_CONFIG_PSEL_Msk);
|
||||||
|
|
||||||
|
if (input != NRF_ADC_CONFIG_INPUT_DISABLED)
|
||||||
|
{
|
||||||
|
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for retrieving the ADC conversion result.
|
||||||
|
*
|
||||||
|
* This function retrieves and returns the last analog-to-digital conversion result.
|
||||||
|
*
|
||||||
|
* @return Last conversion result.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE int32_t nrf_adc_result_get(void)
|
||||||
|
{
|
||||||
|
return (int32_t)NRF_ADC->RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for checking whether the ADC is busy.
|
||||||
|
*
|
||||||
|
* This function checks whether the analog-to-digital converter is busy with a conversion.
|
||||||
|
*
|
||||||
|
* @retval true If the ADC is busy.
|
||||||
|
* @retval false If the ADC is not busy.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE bool nrf_adc_is_busy(void)
|
||||||
|
{
|
||||||
|
return ( (NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == ADC_BUSY_BUSY_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for getting the ADC's enabled interrupts.
|
||||||
|
*
|
||||||
|
* @param[in] mask Mask of interrupts to check.
|
||||||
|
*
|
||||||
|
* @return State of the interrupts selected by the mask.
|
||||||
|
*
|
||||||
|
* @sa nrf_adc_int_enable()
|
||||||
|
* @sa nrf_adc_int_disable()
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t nrf_adc_int_get(uint32_t mask)
|
||||||
|
{
|
||||||
|
return (NRF_ADC->INTENSET & mask); // when read this register will return the value of INTEN.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for starting conversion.
|
||||||
|
*
|
||||||
|
* @sa nrf_adc_stop()
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_start(void)
|
||||||
|
{
|
||||||
|
NRF_ADC->TASKS_START = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for stopping conversion.
|
||||||
|
*
|
||||||
|
* If the analog-to-digital converter is in inactive state, power consumption is reduced.
|
||||||
|
*
|
||||||
|
* @sa nrf_adc_start()
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_stop(void)
|
||||||
|
{
|
||||||
|
NRF_ADC->TASKS_STOP = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for checking if the requested ADC conversion has ended.
|
||||||
|
*
|
||||||
|
* @retval true If the task has finished.
|
||||||
|
* @retval false If the task is still running.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE bool nrf_adc_conversion_finished(void)
|
||||||
|
{
|
||||||
|
return ((bool)NRF_ADC->EVENTS_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for clearing the conversion END event.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_conversion_event_clean(void)
|
||||||
|
{
|
||||||
|
NRF_ADC->EVENTS_END = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for getting the address of an ADC task register.
|
||||||
|
*
|
||||||
|
* @param[in] adc_task ADC task.
|
||||||
|
*
|
||||||
|
* @return Address of the specified ADC task.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for getting the address of a specific ADC event register.
|
||||||
|
*
|
||||||
|
* @param[in] adc_event ADC event.
|
||||||
|
*
|
||||||
|
* @return Address of the specified ADC event.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for setting the CONFIG register in ADC.
|
||||||
|
*
|
||||||
|
* @param[in] configuration Value to be written to the CONFIG register.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for clearing an ADC event.
|
||||||
|
*
|
||||||
|
* @param[in] event Event to clear.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for checking state of an ADC event.
|
||||||
|
*
|
||||||
|
* @param[in] event Event to check.
|
||||||
|
*
|
||||||
|
* @retval true If the event is set.
|
||||||
|
* @retval false If the event is not set.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for enabling specified interrupts.
|
||||||
|
*
|
||||||
|
* @param[in] int_mask Interrupts to enable.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for disabling specified interrupts.
|
||||||
|
*
|
||||||
|
* @param[in] int_mask Interrupts to disable.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for retrieving the state of a given interrupt.
|
||||||
|
*
|
||||||
|
* @param[in] int_mask Interrupt to check.
|
||||||
|
*
|
||||||
|
* @retval true If the interrupt is enabled.
|
||||||
|
* @retval false If the interrupt is not enabled.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for activating a specific ADC task.
|
||||||
|
*
|
||||||
|
* @param[in] task Task to activate.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for enabling ADC.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_enable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function for disabling ADC.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void nrf_adc_disable(void);
|
||||||
|
|
||||||
|
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task)
|
||||||
|
{
|
||||||
|
return (uint32_t)((uint8_t *)NRF_ADC + adc_task);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event)
|
||||||
|
{
|
||||||
|
return (uint32_t)((uint8_t *)NRF_ADC + adc_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration)
|
||||||
|
{
|
||||||
|
NRF_ADC->CONFIG = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event)) = 0x0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event)
|
||||||
|
{
|
||||||
|
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask)
|
||||||
|
{
|
||||||
|
NRF_ADC->INTENSET = int_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask)
|
||||||
|
{
|
||||||
|
NRF_ADC->INTENCLR = int_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask)
|
||||||
|
{
|
||||||
|
return (bool)(NRF_ADC->INTENSET & int_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task)
|
||||||
|
{
|
||||||
|
*((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)task)) = 0x1UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_enable(void)
|
||||||
|
{
|
||||||
|
NRF_ADC->ENABLE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE void nrf_adc_disable(void)
|
||||||
|
{
|
||||||
|
NRF_ADC->ENABLE = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* NRF52 */
|
||||||
|
/**
|
||||||
|
*@}
|
||||||
|
**/
|
||||||
|
|
||||||
|
#endif /* NRF_ADC_H_ */
|
Loading…
Reference in New Issue