add files from nrf52832 bootloader project

This commit is contained in:
hathach
2018-02-07 23:32:49 +07:00
parent ac1f0e7955
commit 9f1d9f321e
186 changed files with 83021 additions and 0 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -0,0 +1,414 @@
/* 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_CLOCK_H__
#define NRF_CLOCK_H__
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
/**
* @defgroup nrf_clock_hal Clock HAL
* @{
* @ingroup nrf_clock
* @brief Hardware access layer for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK).
*/
#define NRF_CLOCK_TASK_TRIGGER (1UL)
#define NRF_CLOCK_EVENT_CLEAR (0UL)
/**
* @brief Low-frequency clock sources.
* @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers.
*/
typedef enum
{
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */
NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */
} nrf_clock_lfclk_t;
/**
* @brief High-frequency clock sources.
*/
typedef enum
{
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */
NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
} nrf_clock_hfclk_t;
/**
* @brief Trigger status of task LFCLKSTART/HFCLKSTART.
* @details Used by LFCLKRUN and HFCLKRUN registers.
*/
typedef enum
{
NRF_CLOCK_START_TASK_NOT_TRIGGERED = CLOCK_LFCLKRUN_STATUS_NotTriggered, /**< Task LFCLKSTART/HFCLKSTART has not been triggered. */
NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */
} nrf_clock_start_task_status_t;
/**
* @brief Crystal frequency selection.
*/
typedef enum
{
#ifdef NRF51
NRF_CLOCK_XTALFREQ_Default = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< Default. 32 MHz. */
NRF_CLOCK_XTALFREQ_16MHz = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< 16 MHz crystal. */
NRF_CLOCK_XTALFREQ_32MHz = CLOCK_XTALFREQ_XTALFREQ_32MHz /**< 32 MHz crystal. */
#elif defined NRF52
NRF_CLOCK_XTALFREQ_Default, /**< Default. 64MHz. */
#endif
} nrf_clock_xtalfreq_t;
/**
* @brief Interrupts.
*/
typedef enum
{
NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */
NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */
NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */
NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk /**< Interrupt on CTTO event. */
} nrf_clock_int_mask_t;
/**
* @brief Tasks.
*
* @details The NRF_CLOCK_TASK_LFCLKSTOP task cannot be set when the low-frequency clock is not running.
* The NRF_CLOCK_TASK_HFCLKSTOP task cannot be set when the high-frequency clock is not running.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/
NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/
NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/
NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/
NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/
NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/
NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/
} nrf_clock_task_t; /*lint -restore */
/**
* @brief Events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/
NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started.*/
NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/
NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO) /**< Calibration timer time-out.*/
} nrf_clock_event_t; /*lint -restore */
/**
* @brief Function for enabling a specific interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask);
/**
* @brief Function for disabling a specific interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask);
/**
* @brief Function for retrieving the state of a specific interrupt.
*
* @param[in] int_mask Interrupt.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask);
/**
* @brief Function for retrieving the address of a specific task.
* @details This function can be used by the PPI module.
*
* @param[in] task Task.
*
* @return Address of the requested task register.
*/
__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task);
/**
* @brief Function for setting a specific task.
*
* @param[in] task Task.
*/
__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task);
/**
* @brief Function for retrieving the address of a specific event.
* @details This function can be used by the PPI module.
*
* @param[in] event Event.
*
* @return Address of the requested event register.
*/
__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event);
/**
* @brief Function for clearing a specific event.
*
* @param[in] event Event.
*/
__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event);
/**
* @brief Function for retrieving the state of a specific event.
*
* @param[in] event Event.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event);
/**
* @brief Function for changing the low-frequency clock source.
* @details This function cannot be called when the low-frequency clock is running.
*
* @param[in] source New low-frequency clock source.
*
*/
__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source);
/**
* @brief Function for retrieving the selected source for the low-frequency clock.
*
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock.
*/
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void);
/**
* @brief Function for retrieving the active source of the low-frequency clock.
*
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock.
*/
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void);
/**
* @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered.
*
* @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock.
* @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock.
* @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock.
*/
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void);
/**
* @brief Function for retrieving the state of the LFCLK clock.
*
* @retval false If the LFCLK clock is not running.
* @retval true If the LFCLK clock is running.
*/
__STATIC_INLINE bool nrf_clock_lf_is_running(void);
/**
* @brief Function for retrieving the trigger status of the task LFCLKSTART.
*
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered.
* @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered.
*/
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void);
/**
* @brief Function for retrieving the active source of the high-frequency clock.
*
* @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock.
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock.
*/
__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void);
/**
* @brief Function for retrieving the state of the HFCLK clock.
*
* @param[in] clk_src Clock source to be checked.
*
* @retval false If the HFCLK clock is not running.
* @retval true If the HFCLK clock is running.
*/
__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src);
/**
* @brief Function for retrieving the trigger status of the task HFCLKSTART.
*
* @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered.
* @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered.
*/
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void);
/**
* @brief Function for retrieving the frequency selection of the external crystal.
*
* @retval NRF_CLOCK_XTALFREQ_16MHz If a 16 MHz crystal is used as source for the HFCLK oscillator.
* @retval NRF_CLOCK_XTALFREQ_32MHz If a 32 MHz crystal is used as source for the HFCLK oscillator.
*/
__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void);
/**
* @brief Function for changing the frequency selection of the external crystal.
*
* @param[in] xtalfreq New frequency selection for the external crystal.
*/
__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq);
/**
* @brief Function for changing the calibration timer interval.
*
* @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds).
*/
__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask)
{
NRF_CLOCK->INTENSET = int_mask;
}
__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask)
{
NRF_CLOCK->INTENCLR = int_mask;
}
__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask)
{
return (bool)(NRF_CLOCK->INTENCLR & int_mask);
}
__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task)
{
return ((uint32_t )NRF_CLOCK + task);
}
__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task)
{
*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER;
}
__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event)
{
return ((uint32_t)NRF_CLOCK + event);
}
__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event)
{
*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event)
{
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event));
}
__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source)
{
NRF_CLOCK->LFCLKSRC =
(uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
}
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void)
{
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC &
CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos);
}
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void)
{
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT &
CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos);
}
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void)
{
return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY &
CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos);
}
__STATIC_INLINE bool nrf_clock_lf_is_running(void)
{
return ((NRF_CLOCK->LFCLKSTAT &
CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos);
}
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void)
{
return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN &
CLOCK_LFCLKRUN_STATUS_Msk) >>
CLOCK_LFCLKRUN_STATUS_Pos);
}
__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void)
{
return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT &
CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos);
}
__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src)
{
return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) ==
(CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos));
}
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void)
{
return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN &
CLOCK_HFCLKRUN_STATUS_Msk) >>
CLOCK_HFCLKRUN_STATUS_Pos);
}
__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void)
{
#ifdef NRF51
return (nrf_clock_xtalfreq_t)((NRF_CLOCK->XTALFREQ &
CLOCK_XTALFREQ_XTALFREQ_Msk) >> CLOCK_XTALFREQ_XTALFREQ_Pos);
#elif defined NRF52
return NRF_CLOCK_XTALFREQ_Default;
#endif
}
__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq)
{
#ifdef NRF51
NRF_CLOCK->XTALFREQ =
(uint32_t)((xtalfreq << CLOCK_XTALFREQ_XTALFREQ_Pos) & CLOCK_XTALFREQ_XTALFREQ_Msk);
#elif defined NRF52
return;
#endif
}
__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval)
{
NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/**
*@}
**/
#endif // NRF_CLOCK_H__

View File

@ -0,0 +1,469 @@
/* 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.
*
*/
/**
* @file
* @brief COMP HAL API.
*/
#ifndef NRF_COMP_H_
#define NRF_COMP_H_
/**
* @defgroup nrf_comp_hal COMP HAL
* @{
* @ingroup nrf_comp
* @brief @tagAPI52 Hardware access layer for managing the Comparator (COMP).
*/
#include "nrf.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**
* @enum nrf_comp_input_t
* @brief COMP analog pin selection.
*/
typedef enum
{
NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */
NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */
NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */
NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */
NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */
NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */
NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */
NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7 /*!< AIN7 selected as analog input. */
}nrf_comp_input_t;
/**
* @enum nrf_comp_ref_t
* @brief COMP reference selection.
*/
typedef enum
{
NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */
NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */
NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */
NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */
NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */
}nrf_comp_ref_t;
/**
* @enum nrf_comp_ext_ref_t
* @brief COMP external analog reference selection.
*/
typedef enum
{
NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */
NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */
}nrf_comp_ext_ref_t;
/**
* @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP.
*/
typedef struct
{
uint8_t th_down; /*!< THDOWN value. */
uint8_t th_up; /*!< THUP value. */
}nrf_comp_th_t;
/**
* @enum nrf_comp_main_mode_t
* @brief COMP main operation mode.
*/
typedef enum
{
NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */
NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */
}nrf_comp_main_mode_t;
/**
* @enum nrf_comp_sp_mode_t
* @brief COMP speed and power mode.
*/
typedef enum
{
NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */
NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */
NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */
}nrf_comp_sp_mode_t;
/**
* @enum nrf_comp_hyst_t
* @brief COMP comparator hysteresis.
*/
typedef enum
{
NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */
NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */
}nrf_comp_hyst_t;
/**
* @brief COMP current source selection on analog input.
*/
typedef enum
{
NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */
NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */
NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */
NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */
}nrf_isource_t;
/**
* @enum nrf_comp_task_t
* @brief COMP tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */
NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */
NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */
/*lint -restore*/
}nrf_comp_task_t;
/**
* @enum nrf_comp_event_t
* @brief COMP events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */
NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */
NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */
NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */
/*lint -restore*/
}nrf_comp_event_t;
/**
* @brief COMP reference configuration.
*/
typedef struct
{
nrf_comp_ref_t reference; /*!< COMP reference selection. */
nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */
}nrf_comp_ref_conf_t;
/**
* @brief Function for enabling the COMP peripheral.
*/
__STATIC_INLINE void nrf_comp_enable(void);
/**
* @brief Function for disabling the COMP peripheral.
*/
__STATIC_INLINE void nrf_comp_disable(void);
/**
* @brief Function for checking if the COMP peripheral is enabled.
*
* @retval true If the COMP peripheral is enabled.
* @retval false If the COMP peripheral is not enabled.
*/
__STATIC_INLINE bool nrf_comp_enable_check(void);
/**
* @brief Function for setting the reference source.
*
* @param[in] reference COMP reference selection.
*/
__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference);
/**
* @brief Function for setting the external analog reference source.
*
* @param[in] ext_ref COMP external analog reference selection.
*/
__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref);
/**
* @brief Function for setting threshold voltages.
*
* @param[in] threshold COMP VDOWN and VUP thresholds.
*/
__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold);
/**
* @brief Function for setting the main mode.
*
* @param[in] main_mode COMP main operation mode.
*/
__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode);
/**
* @brief Function for setting the speed mode.
*
* @param[in] speed_mode COMP speed and power mode.
*/
__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode);
/**
* @brief Function for setting the hysteresis.
*
* @param[in] hyst COMP comparator hysteresis.
*/
__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst);
/**
* @brief Function for setting the current source on the analog input.
*
* @param[in] isource COMP current source selection on analog input.
*/
__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource);
/**
* @brief Function for selecting the active input of the COMP.
*
* @param[in] input Input to be selected.
*/
__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input);
/**
* @brief Function for getting the last COMP compare result.
*
* @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-.
*
* @note If VIN+ == VIN-, the return value depends on the previous result.
*/
__STATIC_INLINE uint32_t nrf_comp_result_get(void);
/**
* @brief Function for enabling interrupts from COMP.
*
* @param[in] comp_int_mask Mask of interrupts to be enabled.
*
* @sa nrf_comp_int_enable_check()
*/
__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask);
/**
* @brief Function for disabling interrupts from COMP.
*
* @param[in] comp_int_mask Mask of interrupts to be disabled.
*
* @sa nrf_comp_int_enable_check()
*/
__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask);
/**
* @brief Function for getting the enabled interrupts of COMP.
*
* @param[in] comp_int_mask Mask of interrupts to be checked.
*
* @retval true If any interrupts of the specified mask are enabled.
*/
__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask);
/**
* @brief Function for getting the address of a specific COMP task register.
*
* @param[in] comp_task COMP task.
*
* @return Address of the specified COMP task.
*/
__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task);
/**
* @brief Function for getting the address of a specific COMP event register.
*
* @param[in] comp_event COMP event.
*
* @return Address of the specified COMP event.
*/
__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event);
/**
* @brief Function for setting COMP shorts.
*
* @param[in] comp_short_mask COMP shorts by mask.
*
*/
__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask);
/**
* @brief Function for clearing COMP shorts by mask.
*
* @param[in] comp_short_mask COMP shorts to be cleared.
*
*/
__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask);
/**
* @brief Function for setting a specific COMP task.
*
* @param[in] comp_task COMP task to be set.
*
*/
__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task);
/**
* @brief Function for clearing a specific COMP event.
*
* @param[in] comp_event COMP event to be cleared.
*
*/
__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event);
/**
* @brief Function for getting the state of a specific COMP event.
*
* @retval true If the specified COMP event is active.
*
*/
__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_comp_enable(void)
{
NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_comp_disable(void)
{
NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE bool nrf_comp_enable_check(void)
{
return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled);
}
__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference)
{
NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos);
}
__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref)
{
NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos);
}
__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold)
{
NRF_COMP->TH =
((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) |
((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk);
}
__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode)
{
NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos);
}
__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode)
{
NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos);
}
__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst)
{
NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk;
}
__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource)
{
NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk;
}
__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input)
{
NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos);
}
__STATIC_INLINE uint32_t nrf_comp_result_get(void)
{
return (uint32_t)NRF_COMP->RESULT;
}
__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask)
{
NRF_COMP->INTENSET = comp_int_mask;
}
__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask)
{
NRF_COMP->INTENCLR = comp_int_mask;
}
__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask)
{
return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN.
}
__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task)
{
return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task);
}
__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event)
{
return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event);
}
__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask)
{
NRF_COMP->SHORTS |= comp_short_mask;
}
__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask)
{
NRF_COMP->SHORTS &= ~comp_short_mask;
}
__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1;
}
__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0;
}
__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event)
{
return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event));
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/**
*@}
**/
#endif // NRF_COMP_H_

View File

@ -0,0 +1,74 @@
/* Copyright (c) 2012 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.
*
* $LastChangedRevision: 25419 $
*/
/**
* @file
* @brief Implementation of AES ECB driver
*/
//lint -e438
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "nrf.h"
#include "nrf_ecb.h"
static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access.
static uint8_t* ecb_key; ///< Key: Starts at ecb_data
static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes.
static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes.
bool nrf_ecb_init(void)
{
ecb_key = ecb_data;
ecb_cleartext = ecb_data + 16;
ecb_ciphertext = ecb_data + 32;
NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data;
return true;
}
bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf)
{
uint32_t counter = 0x1000000;
if(src_buf != ecb_cleartext)
{
memcpy(ecb_cleartext,src_buf,16);
}
NRF_ECB->EVENTS_ENDECB = 0;
NRF_ECB->TASKS_STARTECB = 1;
while(NRF_ECB->EVENTS_ENDECB == 0)
{
counter--;
if(counter == 0)
{
return false;
}
}
NRF_ECB->EVENTS_ENDECB = 0;
if(dest_buf != ecb_ciphertext)
{
memcpy(dest_buf,ecb_ciphertext,16);
}
return true;
}
void nrf_ecb_set_key(const uint8_t * key)
{
memcpy(ecb_key,key,16);
}

View File

@ -0,0 +1,66 @@
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential 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.
*
* $LastChangedRevision: 13999 $
*/
/**
* @file
* @brief ECB driver API.
*/
#ifndef NRF_ECB_H__
#define NRF_ECB_H__
/**
* @defgroup nrf_ecb AES ECB encryption
* @{
* @ingroup nrf_drivers
* @brief Driver for the AES Electronic Code Book (ECB) peripheral.
*
* To encrypt and decrypt data, the peripheral must first be powered on
* using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key.
*/
#include <stdint.h>
/**
* @brief Function for initializing and powering on the ECB peripheral.
*
* This function allocates memory for the ECBDATAPTR.
* @retval true If initialization was successful.
* @retval false If powering on failed.
*/
bool nrf_ecb_init(void);
/**
* @brief Function for encrypting and decrypting 16-byte data using current key.
*
* This function avoids unnecessary copying of data if the parameters point to the
* correct locations in the ECB data structure.
*
* @param dst Result of encryption/decryption. 16 bytes will be written.
* @param src Source with 16-byte data to be encrypted/decrypted.
*
* @retval true If the encryption operation completed.
* @retval false If the encryption operation did not complete.
*/
bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src);
/**
* @brief Function for setting the key to be used for encryption and decryption.
*
* @param key Pointer to the key. 16 bytes will be read.
*/
void nrf_ecb_set_key(const uint8_t * key);
#endif // NRF_ECB_H__
/** @} */

View File

@ -0,0 +1,286 @@
/* 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_EGU_H__
#define NRF_EGU_H__
#ifndef NRF52
#error EGU is not supported on your chip.
#endif
/**
* @defgroup nrf_egu EGU (Event Generator Unit) abstraction
* @{
* @ingroup nrf_drivers
* @brief @tagAPI52 EGU (Event Generator Unit) module functions.
*
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_assert.h"
#include "nrf.h"
#define NRF_EGU_COUNT 6 /**< Number of EGU instances. */
#define NRF_EGU_CHANNEL_COUNT 16 /**< Number of channels per EGU instance. */
/**
* @enum nrf_egu_task_t
* @brief EGU tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */
NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */
NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */
NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */
NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */
NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */
NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */
NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */
NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */
NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */
NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */
NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */
NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */
NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */
NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */
NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */
/*lint -restore*/
} nrf_egu_task_t;
/**
* @enum nrf_egu_event_t
* @brief EGU events.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */
NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */
NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */
NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */
NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */
NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */
NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */
NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */
NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */
NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */
NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */
NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */
NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */
NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */
NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */
NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */
/*lint -restore*/
} nrf_egu_event_t;
/**
* @enum nrf_egu_int_mask_t
* @brief EGU interrupts.
*/
typedef enum
{
NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */
NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */
NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */
NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */
NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */
NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */
NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */
NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */
NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */
NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */
NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */
NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */
NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */
NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */
NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */
NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */
NRF_EGU_INT_ALL = 0xFFFFuL
} nrf_egu_int_mask_t;
/**
* @brief Function for triggering a specific EGU task.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL;
}
/**
* @brief Function for returning the address of a specific EGU task register.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_task_t egu_task)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGER task register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_trigger_addres_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < NRF_EGU_CHANNEL_COUNT);
return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGER task.
*
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(uint8_t channel)
{
ASSERT(channel <= NRF_EGU_CHANNEL_COUNT);
return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for returning the state of a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to check.
*/
__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for clearing a specific EGU event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to clear.
*/
__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL;
}
/**
* @brief Function for returning the address of a specific EGU event register.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
/**
* @brief Function for returning the address of a specific EGU TRIGGERED event register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_triggered_addres_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
ASSERT(channel < NRF_EGU_CHANNEL_COUNT);
return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel];
}
/**
* @brief Function for returning the specific EGU TRIGGERED event.
*
* @param channel Channel number.
*/
__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(uint8_t channel)
{
ASSERT(channel < NRF_EGU_CHANNEL_COUNT);
return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t)));
}
/**
* @brief Function for enabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENSET = egu_int_mask;
}
/**
* @brief Function for retrieving the state of one or more EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to check.
*
* @retval true If all of the specified interrupts are enabled.
* @retval false If at least one of the specified interrupts is disabled.
*/
__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
return (bool)(NRF_EGUx->INTENSET & egu_int_mask);
}
/**
* @brief Function for disabling one or more specific EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param egu_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask)
{
NRF_EGUx->INTENCLR = egu_int_mask;
}
/**
* @brief Function for retrieving one or more specific EGU interrupts.
*
* @param channel Channel number.
*
* @returns EGU interrupt mask.
*/
__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(uint8_t channel)
{
ASSERT(channel < NRF_EGU_CHANNEL_COUNT);
return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel));
}
/** @} */
#endif

View File

@ -0,0 +1,647 @@
/* 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_GPIO_H__
#define NRF_GPIO_H__
#include "nrf.h"
#include <stdbool.h>
/**
* @defgroup nrf_gpio GPIO abstraction
* @{
* @ingroup nrf_drivers
* @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports.
*
* Here, the GPIO ports are defined as follows:
* - Port 0 -> pin 0-7
* - Port 1 -> pin 8-15
* - Port 2 -> pin 16-23
* - Port 3 -> pin 24-31
*/
#define NUMBER_OF_PINS 32
/**
* @brief Enumerator used for selecting between port 0 - 3.
*/
typedef enum
{
NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7)
NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15)
NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23)
NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31)
} nrf_gpio_port_select_t;
/**
* @brief Enumerator used for setting the direction of a GPIO port.
*/
typedef enum
{
NRF_GPIO_PORT_DIR_OUTPUT, ///< Output
NRF_GPIO_PORT_DIR_INPUT ///< Input
} nrf_gpio_port_dir_t;
/**
* @brief Pin direction definitions.
*/
typedef enum
{
NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input
NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output
} nrf_gpio_pin_dir_t;
/**
* @brief Connection of input buffer
*/
typedef enum
{
NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer
NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer
} nrf_gpio_pin_input_t;
/**
* @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration
*/
typedef enum
{
NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled
NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled
NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled
} nrf_gpio_pin_pull_t;
/**
* @brief Enumerator used for selecting output drive mode
*/
typedef enum
{
NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'
NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1'
NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1'
NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1''
NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'
NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1'
NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1'
NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1'
} nrf_gpio_pin_drive_t;
/**
* @brief Enumerator used for selecting the pin to sense high or low level on the pin input.
*/
typedef enum
{
NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled.
NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level.
NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level.
} nrf_gpio_pin_sense_t;
/**
* @brief Function for configuring the GPIO pin range as outputs with normal drive strength.
* This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
*
* @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
*
* @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
*
* @note For configuring only one pin as output use @ref nrf_gpio_cfg_output
* Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
*/
__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end);
/**
* @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details.
* This function can be used to configure pin range as simple input.
*
* @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
*
* @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
*
* @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high)
*
* @note For configuring only one pin as input use @ref nrf_gpio_cfg_input
* Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
*/
__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config);
/**
* @brief Pin configuration function
*
* The main pin configuration function.
* This function allows to set any aspect in PIN_CNF register.
* @param pin_number Specifies the pin number (allowed values 0-31).
* @param dir Pin direction
* @param input Connect or disconnect input buffer
* @param pull Pull configuration
* @param drive Drive configuration
* @param sense Pin sensing mechanism
*/
__STATIC_INLINE void nrf_gpio_cfg(
uint32_t pin_number,
nrf_gpio_pin_dir_t dir,
nrf_gpio_pin_input_t input,
nrf_gpio_pin_pull_t pull,
nrf_gpio_pin_drive_t drive,
nrf_gpio_pin_sense_t sense);
/**
* @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details.
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
*
* @param pin_number specifies the pin number (allowed values 0-31)
*
* @note Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
*/
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
/**
* @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
*
* @param pin_number Specifies the pin number (allowed values 0-30).
* @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high).
*
* @note Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
*/
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
/**
* @brief Function for reseting pin configuration to its default state.
*
* @param pin_number Specifies the pin number (allowed values 0-31).
*/
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
/**
* @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
*
* @param pin_number Specifies the pin number (allowed values 0-31).
*
*/
__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number);
/**
* @brief Function for disconnecting input for the given GPIO.
*
* @param pin_number Specifies the pin number (allowed values 0-31).
*
*/
__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number);
/**
* @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
* Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable.
*
* @param pin_number Specifies the pin number (allowed values 0-30).
* @param pull_config State of the pin pull resistor (no pull, pulled down or pulled high).
* @param sense_config Sense level of the pin (no sense, sense low or sense high).
*/
__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config);
/**
* @brief Function for configuring sense level for the given GPIO.
*
* @param pin_number Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30).
* @param sense_config Sense configuration.
*
*/
__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config);
/**
* @brief Function for setting the direction for a GPIO pin.
*
* @param pin_number specifies the pin number (0-31) for which to
* set the direction.
*
* @param direction specifies the direction
*/
__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction);
/**
* @brief Function for setting a GPIO pin.
*
* Note that the pin must be configured as an output for this
* function to have any effect.
*
* @param pin_number Specifies the pin number (0-31) to set.
*/
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
/**
* @brief Function for setting GPIO pins.
*
* Note that the pins must be configured as outputs for this
* function to have any effect.
*
* @param pin_mask Specifies the pins to set.
*/
__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask);
/**
* @brief Function for clearing a GPIO pin.
*
* Note that the pin must be configured as an output for this
* function to have any effect.
*
* @param pin_number Specifies the pin number (0-31) to clear.
*/
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
/**
* @brief Function for clearing GPIO pins.
*
* Note that the pins must be configured as outputs for this
* function to have any effect.
*
* @param pin_mask Specifies the pins to clear.
*/
__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask);
/**
* @brief Function for toggling a GPIO pin.
*
* Note that the pin must be configured as an output for this
* function to have any effect.
*
* @param pin_number Specifies the pin number (0-31) to toggle.
*/
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
/**
* @brief Function for toggling GPIO pins.
*
* Note that the pins must be configured as outputs for this
* function to have any effect.
*
* @param pin_mask Specifies the pins to toggle.
*/
__STATIC_INLINE void nrf_gpio_pins_toggle(uint32_t pin_mask);
/**
* @brief Function for writing a value to a GPIO pin.
*
* Note that the pin must be configured as an output for this
* function to have any effect.
*
* @param pin_number specifies the pin number (0-31) to
* write.
*
* @param value specifies the value to be written to the pin.
* @arg 0 clears the pin
* @arg >=1 sets the pin.
*/
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value);
/**
* @brief Function for reading the input level of a GPIO pin.
*
* Note that the pin must have input connected for the value
* returned from this function to be valid.
*
* @param pin_number specifies the pin number (0-31) to
* read.
*
* @return
* @retval 0 if the pin input level is low.
* @retval 1 if the pin input level is high.
* @retval > 1 should never occur.
*/
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
/**
* @brief Function for reading the input level of all GPIO pins.
*
* Note that the pin must have input connected for the value
* returned from this function to be valid.
*
* @retval Status of input of all pins
*/
__STATIC_INLINE uint32_t nrf_gpio_pins_read(void);
/**
* @brief Function for reading the sense configuration of a GPIO pin.
*
* @param pin_number specifies the pin number (0-31) to
* read.
*
* @retval Sense configuration
*/
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number);
/**
* @brief Generic function for writing a single byte of a 32 bit word at a given
* address.
*
* This function should not be called from outside the nrf_gpio
* abstraction layer.
*
* @param word_address is the address of the word to be written.
*
* @param byte_no is the word byte number (0-3) to be written.
*
* @param value is the value to be written to byte "byte_no" of word
* at address "word_address"
*/
__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value);
/**
* @brief Generic function for reading a single byte of a 32 bit word at a given
* address.
*
* This function should not be called from outside the nrf_gpio
* abstraction layer.
*
* @param word_address is the address of the word to be read.
*
* @param byte_no is the byte number (0-3) of the word to be read.
*
* @return byte "byte_no" of word at address "word_address".
*/
__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no);
/**
* @brief Function for setting the direction of a port.
*
* @param port is the port for which to set the direction.
*
* @param dir direction to be set for this port.
*/
__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir);
/**
* @brief Function for reading a GPIO port.
*
* @param port is the port to read.
*
* @return the input value on this port.
*/
__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port);
/**
* @brief Function for writing to a GPIO port.
*
* @param port is the port to write.
*
* @param value is the value to write to this port.
*
* @sa nrf_gpio_port_dir_set()
*/
__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value);
/**
* @brief Function for setting individual pins on GPIO port.
*
* @param port is the port for which to set the pins.
*
* @param set_mask is a mask specifying which pins to set. A bit
* set to 1 indicates that the corresponding port pin shall be
* set.
*
* @sa nrf_gpio_port_dir_set()
*/
__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask);
/**
* @brief Function for clearing individual pins on GPIO port.
*
* @param port is the port for which to clear the pins.
*
* @param clr_mask is a mask specifying which pins to clear. A bit
* set to 1 indicates that the corresponding port pin shall be
* cleared.
*
* @sa nrf_gpio_port_dir_set()
*/
__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
for (; pin_range_start <= pin_range_end; pin_range_start++)
{
nrf_gpio_cfg_output(pin_range_start);
}
}
__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
for (; pin_range_start <= pin_range_end; pin_range_start++)
{
nrf_gpio_cfg_input(pin_range_start, pull_config);
}
}
__STATIC_INLINE void nrf_gpio_cfg(
uint32_t pin_number,
nrf_gpio_pin_dir_t dir,
nrf_gpio_pin_input_t input,
nrf_gpio_pin_pull_t pull,
nrf_gpio_pin_drive_t drive,
nrf_gpio_pin_sense_t sense)
{
NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
| ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos)
| ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos)
| ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
| ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos);
}
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
{
nrf_gpio_cfg(
pin_number,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
}
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
{
nrf_gpio_cfg(
pin_number,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
pull_config,
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
}
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number)
{
nrf_gpio_cfg(
pin_number,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
}
__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos);
}
__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
}
__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config)
{
nrf_gpio_cfg(
pin_number,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
pull_config,
NRF_GPIO_PIN_S0S1,
sense_config);
}
__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
//uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk;
NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk;
NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos);
}
__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)
{
if(direction == NRF_GPIO_PIN_DIR_INPUT)
{
nrf_gpio_cfg(
pin_number,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_S0S1,
NRF_GPIO_PIN_NOSENSE);
}
else
{
NRF_GPIO->DIRSET = (1UL << pin_number);
}
}
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number)
{
NRF_GPIO->OUTSET = (1UL << pin_number);
}
__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask)
{
NRF_GPIO->OUTSET = pin_mask;
}
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
{
NRF_GPIO->OUTCLR = (1UL << pin_number);
}
__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask)
{
NRF_GPIO->OUTCLR = pin_mask;
}
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
{
nrf_gpio_pins_toggle(1UL << pin_number);
}
__STATIC_INLINE void nrf_gpio_pins_toggle(uint32_t pin_mask)
{
uint32_t pins_state = NRF_GPIO->OUT;
NRF_GPIO->OUTSET = (~pins_state & pin_mask);
NRF_GPIO->OUTCLR = ( pins_state & pin_mask);
}
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
{
if (value == 0)
{
nrf_gpio_pin_clear(pin_number);
}
else
{
nrf_gpio_pin_set(pin_number);
}
}
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
{
return ((NRF_GPIO->IN >> pin_number) & 1UL);
}
__STATIC_INLINE uint32_t nrf_gpio_pins_read(void)
{
return NRF_GPIO->IN;
}
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number)
{
return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos);
}
__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value)
{
*((volatile uint8_t*)(word_address) + byte_no) = value;
}
__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no)
{
return (*((const volatile uint8_t*)(word_address) + byte_no));
}
__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir)
{
if (dir == NRF_GPIO_PORT_DIR_OUTPUT)
{
nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF);
}
else
{
nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL);
}
}
__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port)
{
return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port);
}
__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value)
{
nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value);
}
__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask)
{
nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask);
}
__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask)
{
nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask);
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#endif

View File

@ -0,0 +1,391 @@
/* 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_GPIOTE_H__
#define NRF_GPIOTE_H__
#include "nrf.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
/**
* @defgroup nrf_gpiote_abs GPIOTE abstraction
* @{
* @ingroup nrf_gpiote
* @brief GPIOTE abstraction for configuration of channels.
*/
#ifdef NRF51
#define NUMBER_OF_GPIO_TE 4
#elif defined(NRF52)
#define NUMBER_OF_GPIO_TE 8
#else
#error "Chip family not specified"
#endif
/**
* @enum nrf_gpiote_polarity_t
* @brief Polarity for the GPIOTE channel.
*/
typedef enum
{
NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi, ///< Low to high.
NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo, ///< High to low.
NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle ///< Toggle.
} nrf_gpiote_polarity_t;
/**
* @enum nrf_gpiote_outinit_t
* @brief Initial output value for the GPIOTE channel.
*/
typedef enum
{
NRF_GPIOTE_INITIAL_VALUE_LOW = GPIOTE_CONFIG_OUTINIT_Low, ///< Low to high.
NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High ///< High to low.
} nrf_gpiote_outinit_t;
/**
* @brief Tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_GPIOTE_TASKS_OUT_0 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
#if (NUMBER_OF_GPIO_TE == 8)
NRF_GPIOTE_TASKS_OUT_4 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/
NRF_GPIOTE_TASKS_OUT_5 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/
NRF_GPIOTE_TASKS_OUT_6 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/
NRF_GPIOTE_TASKS_OUT_7 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/
#endif
#ifdef NRF52
NRF_GPIOTE_TASKS_SET_0 = offsetof(NRF_GPIOTE_Type, TASKS_SET[0]), /**< Set task 0.*/
NRF_GPIOTE_TASKS_SET_1 = offsetof(NRF_GPIOTE_Type, TASKS_SET[1]), /**< Set task 1.*/
NRF_GPIOTE_TASKS_SET_2 = offsetof(NRF_GPIOTE_Type, TASKS_SET[2]), /**< Set task 2.*/
NRF_GPIOTE_TASKS_SET_3 = offsetof(NRF_GPIOTE_Type, TASKS_SET[3]), /**< Set task 3.*/
NRF_GPIOTE_TASKS_SET_4 = offsetof(NRF_GPIOTE_Type, TASKS_SET[4]), /**< Set task 4.*/
NRF_GPIOTE_TASKS_SET_5 = offsetof(NRF_GPIOTE_Type, TASKS_SET[5]), /**< Set task 5.*/
NRF_GPIOTE_TASKS_SET_6 = offsetof(NRF_GPIOTE_Type, TASKS_SET[6]), /**< Set task 6.*/
NRF_GPIOTE_TASKS_SET_7 = offsetof(NRF_GPIOTE_Type, TASKS_SET[7]), /**< Set task 7.*/
NRF_GPIOTE_TASKS_CLR_0 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[0]), /**< Clear task 0.*/
NRF_GPIOTE_TASKS_CLR_1 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[1]), /**< Clear task 1.*/
NRF_GPIOTE_TASKS_CLR_2 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[2]), /**< Clear task 2.*/
NRF_GPIOTE_TASKS_CLR_3 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[3]), /**< Clear task 3.*/
NRF_GPIOTE_TASKS_CLR_4 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[4]), /**< Clear task 4.*/
NRF_GPIOTE_TASKS_CLR_5 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[5]), /**< Clear task 5.*/
NRF_GPIOTE_TASKS_CLR_6 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[6]), /**< Clear task 6.*/
NRF_GPIOTE_TASKS_CLR_7 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[7]), /**< Clear task 7.*/
#endif
/*lint -restore*/
} nrf_gpiote_tasks_t;
/**
* @brief Events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_GPIOTE_EVENTS_IN_0 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/
NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/
NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/
NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/
#if (NUMBER_OF_GPIO_TE == 8)
NRF_GPIOTE_EVENTS_IN_4 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[4]), /**< In event 4.*/
NRF_GPIOTE_EVENTS_IN_5 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[5]), /**< In event 5.*/
NRF_GPIOTE_EVENTS_IN_6 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[6]), /**< In event 6.*/
NRF_GPIOTE_EVENTS_IN_7 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[7]), /**< In event 7.*/
#endif
NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/
/*lint -restore*/
} nrf_gpiote_events_t;
/**
* @enum nrf_gpiote_int_t
* @brief GPIOTE interrupts.
*/
typedef enum
{
NRF_GPIOTE_INT_IN0_MASK = GPIOTE_INTENSET_IN0_Msk, /**< GPIOTE interrupt from IN0. */
NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */
NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */
NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */
#if (NUMBER_OF_GPIO_TE == 8)
NRF_GPIOTE_INT_IN4_MASK = GPIOTE_INTENSET_IN4_Msk, /**< GPIOTE interrupt from IN4. */
NRF_GPIOTE_INT_IN5_MASK = GPIOTE_INTENSET_IN5_Msk, /**< GPIOTE interrupt from IN5. */
NRF_GPIOTE_INT_IN6_MASK = GPIOTE_INTENSET_IN6_Msk, /**< GPIOTE interrupt from IN6. */
NRF_GPIOTE_INT_IN7_MASK = GPIOTE_INTENSET_IN7_Msk, /**< GPIOTE interrupt from IN7. */
#endif
NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */
} nrf_gpiote_int_t;
#if (NUMBER_OF_GPIO_TE == 4)
#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK)
#elif (NUMBER_OF_GPIO_TE == 8)
#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK |\
NRF_GPIOTE_INT_IN4_MASK | NRF_GPIOTE_INT_IN5_MASK |\
NRF_GPIOTE_INT_IN6_MASK | NRF_GPIOTE_INT_IN7_MASK)
#else
#error "Unexpected number of GPIO Tasks and Events"
#endif
/**
* @brief Function for activating a specific GPIOTE task.
*
* @param[in] task Task.
*/
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task);
/**
* @brief Function for getting the address of a specific GPIOTE task.
*
* @param[in] task Task.
*
* @returns Address.
*/
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task);
/**
* @brief Function for getting the state of a specific GPIOTE event.
*
* @param[in] event Event.
*/
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event);
/**
* @brief Function for clearing a specific GPIOTE event.
*
* @param[in] event Event.
*/
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event);
/**
* @brief Function for getting the address of a specific GPIOTE event.
*
* @param[in] event Event.
*
* @return Address
*/
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event);
/**@brief Function for enabling interrupts.
*
* @param[in] mask Interrupt mask to be enabled.
*/
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask);
/**@brief Function for disabling interrupts.
*
* @param[in] mask Interrupt mask to be disabled.
*/
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask);
/**@brief Function for checking if interrupts are enabled.
*
* @param[in] mask Mask of interrupt flags to check.
*
* @return Mask with enabled interrupts.
*/
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask);
/**@brief Function for enabling a GPIOTE event.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx);
/**@brief Function for disabling a GPIOTE event.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx);
/**@brief Function for configuring a GPIOTE event.
*
* @param[in] idx Task-Event index.
* @param[in] pin Pin associated with event.
* @param[in] polarity Transition that should generate an event.
*/
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity);
/**@brief Function for getting the pin associated with a GPIOTE event.
*
* @param[in] idx Task-Event index.
*
* @return Pin number.
*/
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx);
/**@brief Function for getting the polarity associated with a GPIOTE event.
*
* @param[in] idx Task-Event index.
*
* @return Polarity.
*/
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx);
/**@brief Function for enabling a GPIOTE task.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx);
/**@brief Function for disabling a GPIOTE task.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx);
/**@brief Function for configuring a GPIOTE task.
* @note Function is not configuring mode field so task is disabled after this function is called.
*
* @param[in] idx Task-Event index.
* @param[in] pin Pin associated with event.
* @param[in] polarity Transition that should generate an event.
* @param[in] init_val Initial value of pin.
*/
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity,
nrf_gpiote_outinit_t init_val);
/**@brief Function for forcing a specific state on the pin connected to GPIOTE.
*
* @param[in] idx Task-Event index.
* @param[in] init_val Pin state.
*/
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val);
/**@brief Function for resetting a GPIOTE task event configuration to the default state.
*
* @param[in] idx Task-Event index.
*/
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task)
{
*(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task)
{
return ((uint32_t)NRF_GPIOTE + task);
}
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event)
{
return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false;
}
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event)
{
*(uint32_t *)nrf_gpiote_event_addr_get(event) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event)
{
return ((uint32_t)NRF_GPIOTE + event);
}
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask)
{
NRF_GPIOTE->INTENSET = mask;
}
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask)
{
NRF_GPIOTE->INTENCLR = mask;
}
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask)
{
return (NRF_GPIOTE->INTENSET & mask);
}
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event;
}
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event;
}
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity)
{
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk);
}
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx)
{
return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PSEL_Msk) >> GPIOTE_CONFIG_PSEL_Pos);
}
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx)
{
return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos);
}
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
{
uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
/* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
correct state in GPIOTE but not in the OUT register. */
/* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk);
__NOP();
__NOP();
__NOP();
NRF_GPIOTE->CONFIG[idx] = final_config;
}
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task;
}
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
nrf_gpiote_polarity_t polarity,
nrf_gpiote_outinit_t init_val)
{
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk |
GPIOTE_CONFIG_POLARITY_Msk |
GPIOTE_CONFIG_OUTINIT_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) |
((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
}
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val)
{
NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk)
| ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
}
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx)
{
NRF_GPIOTE->CONFIG[idx] = 0;
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#endif

View File

@ -0,0 +1,523 @@
/* 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.
*
*/
/**
* @defgroup nrf_i2s_hal I2S HAL
* @{
* @ingroup nrf_i2s
*
* @brief @tagAPI52 Hardware access layer for managing the Inter-IC Sound (I2S) peripheral.
*/
#ifndef NRF_I2S_H__
#define NRF_I2S_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
/**
* @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set
* function call to specify that a given I2S signal (SDOUT, SDIN, or MCK)
* shall not be connected to a physical pin.
*/
#define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF
/**
* @brief I2S tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled.
NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator.
/*lint -restore*/
} nrf_i2s_task_t;
/**
* @brief I2S events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers.
NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers.
NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped.
/*lint -restore*/
} nrf_i2s_event_t;
/**
* @brief I2S interrupts.
*/
typedef enum
{
NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event.
NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event.
NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event.
} nrf_i2s_int_mask_t;
/**
* @brief I2S modes of operation.
*/
typedef enum
{
NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode.
NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode.
} nrf_i2s_mode_t;
/**
* @brief I2S master clock generator settings.
*/
typedef enum
{
NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled.
// [conversion to 'int' needed to prevent compilers from complaining
// that the provided value (0x80000000UL) is out of range of "int"]
NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz.
NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz.
NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz.
NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz.
NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz.
NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz.
NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz.
NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz.
NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz.
NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz.
NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz.
NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz.
NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz.
NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz.
NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz.
NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz.
} nrf_i2s_mck_t;
/**
* @brief I2S MCK/LRCK ratios.
*/
typedef enum
{
NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32.
NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48.
NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64.
NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96.
NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128.
NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192.
NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256.
NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384.
NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512.
} nrf_i2s_ratio_t;
/**
* @brief I2S sample widths.
*/
typedef enum
{
NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit.
NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit.
NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit.
} nrf_i2s_swidth_t;
/**
* @brief I2S alignments of sample within a frame.
*/
typedef enum
{
NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned.
NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned.
} nrf_i2s_align_t;
/**
* @brief I2S frame formats.
*/
typedef enum
{
NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format.
NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format.
} nrf_i2s_format_t;
/**
* @brief I2S enabled channels.
*/
typedef enum
{
NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo.
NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only.
NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only.
} nrf_i2s_channels_t;
/**
* @brief Function for activating a specific I2S task.
*
* @param[in] p_i2s I2S instance.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s,
nrf_i2s_task_t task);
/**
* @brief Function for getting the address of a specific I2S task register.
*
* @param[in] p_i2s I2S instance.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s,
nrf_i2s_task_t task);
/**
* @brief Function for clearing a specific I2S event.
*
* @param[in] p_i2s I2S instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s,
nrf_i2s_event_t event);
/**
* @brief Function for checking the state of a specific I2S event.
*
* @param[in] p_i2s I2S instance.
* @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_i2s_event_check(NRF_I2S_Type const * p_i2s,
nrf_i2s_event_t event);
/**
* @brief Function for getting the address of a specific I2S event register.
*
* @param[in] p_i2s I2S instance.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s,
nrf_i2s_event_t event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_i2s I2S instance.
* @param[in] mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_i2s I2S instance.
* @param[in] mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_i2s I2S instance.
* @param[in] i2s_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s,
nrf_i2s_int_mask_t i2s_int);
/**
* @brief Function for enabling the I2S peripheral.
*
* @param[in] p_i2s I2S instance.
*/
__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s);
/**
* @brief Function for disabling the I2S peripheral.
*
* @param[in] p_i2s I2S instance.
*/
__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s);
/**
* @brief Function for configuring I2S pins.
*
* Usage of the SDOUT, SDIN, and MCK signals is optional.
* If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_i2s I2S instance.
* @param[in] sck_pin SCK pin number.
* @param[in] lrck_pin LRCK pin number.
* @param[in] mck_pin MCK pin number.
* @param[in] sdout_pin SDOUT pin number.
* @param[in] sdin_pin SDIN pin number.
*/
__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s,
uint32_t sck_pin,
uint32_t lrck_pin,
uint32_t mck_pin,
uint32_t sdout_pin,
uint32_t sdin_pin);
/**
* @brief Function for setting the I2S peripheral configuration.
*
* @param[in] p_i2s I2S instance.
* @param[in] mode Mode of operation (master or slave).
* @param[in] format I2S frame format.
* @param[in] alignment Alignment of sample within a frame.
* @param[in] sample_width Sample width.
* @param[in] channels Enabled channels.
* @param[in] mck_setup Master clock generator setup.
* @param[in] ratio MCK/LRCK ratio.
*
* @retval true If the configuration has been set successfully.
* @retval false If the requested configuration is not allowed.
*/
__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s,
nrf_i2s_mode_t mode,
nrf_i2s_format_t format,
nrf_i2s_align_t alignment,
nrf_i2s_swidth_t sample_width,
nrf_i2s_channels_t channels,
nrf_i2s_mck_t mck_setup,
nrf_i2s_ratio_t ratio);
/**
* @brief Function for setting up the I2S transfer.
*
* This function sets up the RX and TX buffers and enables reception and/or
* transmission accordingly. If the transfer in a given direction is not
* required, pass NULL instead of the pointer to the corresponding buffer.
*
* @param[in] p_i2s I2S instance.
* @param[in] size Size of the buffers (in 32-bit words).
* @param[in] p_rx_buffer Pointer to the receive buffer.
* Pass NULL to disable reception.
* @param[in] p_tx_buffer Pointer to the transmit buffer.
* Pass NULL to disable transmission.
*/
__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s,
uint16_t size,
uint32_t * p_rx_buffer,
uint32_t const * p_tx_buffer);
/**
* @brief Function for setting the pointer to the receive buffer.
*
* @note The size of the buffer can be set only by calling
* @ref nrf_i2s_transfer_set.
*
* @param[in] p_i2s I2S instance.
* @param[in] p_buffer Pointer to the receive buffer.
*/
__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s,
uint32_t * p_buffer);
/**
* @brief Function for getting the pointer to the receive buffer.
*
* @param[in] p_i2s I2S instance.
*
* @return Pointer to the receive buffer.
*/
__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s);
/**
* @brief Function for setting the pointer to the transmit buffer.
*
* @note The size of the buffer can be set only by calling
* @ref nrf_i2s_transfer_set.
*
* @param[in] p_i2s I2S instance.
* @param[in] p_buffer Pointer to the transmit buffer.
*/
__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s,
uint32_t const * p_buffer);
/**
* @brief Function for getting the pointer to the transmit buffer.
*
* @param[in] p_i2s I2S instance.
*
* @return Pointer to the transmit buffer.
*/
__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s,
nrf_i2s_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s,
nrf_i2s_task_t task)
{
return ((uint32_t)p_i2s + (uint32_t)task);
}
__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s,
nrf_i2s_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s,
nrf_i2s_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s,
nrf_i2s_event_t event)
{
return ((uint32_t)p_i2s + (uint32_t)event);
}
__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask)
{
p_i2s->INTENSET = mask;
}
__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask)
{
p_i2s->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s,
nrf_i2s_int_mask_t i2s_int)
{
return (bool)(p_i2s->INTENSET & i2s_int);
}
__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s)
{
p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s)
{
p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s,
uint32_t sck_pin,
uint32_t lrck_pin,
uint32_t mck_pin,
uint32_t sdout_pin,
uint32_t sdin_pin)
{
p_i2s->PSEL.SCK = sck_pin;
p_i2s->PSEL.LRCK = lrck_pin;
p_i2s->PSEL.MCK = mck_pin;
p_i2s->PSEL.SDOUT = sdout_pin;
p_i2s->PSEL.SDIN = sdin_pin;
}
__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s,
nrf_i2s_mode_t mode,
nrf_i2s_format_t format,
nrf_i2s_align_t alignment,
nrf_i2s_swidth_t sample_width,
nrf_i2s_channels_t channels,
nrf_i2s_mck_t mck_setup,
nrf_i2s_ratio_t ratio)
{
if (mode == NRF_I2S_MODE_MASTER)
{
// The MCK/LRCK ratio shall be a multiple of 2 * sample width.
if (((sample_width == NRF_I2S_SWIDTH_16BIT) &&
(ratio == NRF_I2S_RATIO_48X))
||
((sample_width == NRF_I2S_SWIDTH_24BIT) &&
((ratio == NRF_I2S_RATIO_32X) ||
(ratio == NRF_I2S_RATIO_64X) ||
(ratio == NRF_I2S_RATIO_128X) ||
(ratio == NRF_I2S_RATIO_256X) ||
(ratio == NRF_I2S_RATIO_512X))))
{
return false;
}
}
p_i2s->CONFIG.MODE = mode;
p_i2s->CONFIG.FORMAT = format;
p_i2s->CONFIG.ALIGN = alignment;
p_i2s->CONFIG.SWIDTH = sample_width;
p_i2s->CONFIG.CHANNELS = channels;
p_i2s->CONFIG.RATIO = ratio;
if (mck_setup == NRF_I2S_MCK_DISABLED)
{
p_i2s->CONFIG.MCKEN =
(I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
}
else
{
p_i2s->CONFIG.MCKFREQ = mck_setup;
p_i2s->CONFIG.MCKEN =
(I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos);
}
return true;
}
__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s,
uint16_t size,
uint32_t * p_buffer_rx,
uint32_t const * p_buffer_tx)
{
p_i2s->RXTXD.MAXCNT = size;
nrf_i2s_rx_buffer_set(p_i2s, p_buffer_rx);
p_i2s->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0;
nrf_i2s_tx_buffer_set(p_i2s, p_buffer_tx);
p_i2s->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0;
}
__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s,
uint32_t * p_buffer)
{
p_i2s->RXD.PTR = (uint32_t)p_buffer;
}
__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s)
{
return (uint32_t *)(p_i2s->RXD.PTR);
}
__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s,
uint32_t const * p_buffer)
{
p_i2s->TXD.PTR = (uint32_t)p_buffer;
}
__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s)
{
return (uint32_t *)(p_i2s->TXD.PTR);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_I2S_H__
/** @} */

View File

@ -0,0 +1,367 @@
/* 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 LPCOMP HAL API.
*/
#ifndef NRF_LPCOMP_H_
#define NRF_LPCOMP_H_
/**
* @defgroup nrf_lpcomp_hal LPCOMP HAL
* @{
* @ingroup nrf_lpcomp
* @brief Hardware access layer for managing the Low Power Comparator (LPCOMP).
*/
#include "nrf.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**
* @enum nrf_lpcomp_ref_t
* @brief LPCOMP reference selection.
*/
typedef enum
{
#ifdef NRF51
NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */
#elif defined NRF52
NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */
NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */
#endif
NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef |
(LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */
NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef |
(LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */
} nrf_lpcomp_ref_t;
/**
* @enum nrf_lpcomp_input_t
* @brief LPCOMP input selection.
*/
typedef enum
{
NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */
NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */
NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */
NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */
NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */
NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */
NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */
NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */
} nrf_lpcomp_input_t;
/**
* @enum nrf_lpcomp_detect_t
* @brief LPCOMP detection type selection.
*/
typedef enum
{
NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */
NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */
NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */
} nrf_lpcomp_detect_t;
/**
* @enum nrf_lpcomp_task_t
* @brief LPCOMP tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_LPCOMP_TASK_START = offsetof(NRF_LPCOMP_Type, TASKS_START), /**< LPCOMP start sampling task. */
NRF_LPCOMP_TASK_STOP = offsetof(NRF_LPCOMP_Type, TASKS_STOP), /**< LPCOMP stop sampling task. */
NRF_LPCOMP_TASK_SAMPLE = offsetof(NRF_LPCOMP_Type, TASKS_SAMPLE) /**< Sample comparator value. */
} nrf_lpcomp_task_t; /*lint -restore*/
/**
* @enum nrf_lpcomp_event_t
* @brief LPCOMP events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_LPCOMP_EVENT_READY = offsetof(NRF_LPCOMP_Type, EVENTS_READY), /**< LPCOMP is ready and output is valid. */
NRF_LPCOMP_EVENT_DOWN = offsetof(NRF_LPCOMP_Type, EVENTS_DOWN), /**< Input voltage crossed the threshold going down. */
NRF_LPCOMP_EVENT_UP = offsetof(NRF_LPCOMP_Type, EVENTS_UP), /**< Input voltage crossed the threshold going up. */
NRF_LPCOMP_EVENT_CROSS = offsetof(NRF_LPCOMP_Type, EVENTS_CROSS) /**< Input voltage crossed the threshold in any direction. */
} nrf_lpcomp_event_t; /*lint -restore*/
/**
* @enum nrf_lpcomp_short_mask_t
* @brief LPCOMP shorts masks.
*/
typedef enum
{
NRF_LPCOMP_SHORT_CROSS_STOP_MASK = LPCOMP_SHORTS_CROSS_STOP_Msk, /*!< Short between CROSS event and STOP task. */
NRF_LPCOMP_SHORT_UP_STOP_MASK = LPCOMP_SHORTS_UP_STOP_Msk, /*!< Short between UP event and STOP task. */
NRF_LPCOMP_SHORT_DOWN_STOP_MASK = LPCOMP_SHORTS_DOWN_STOP_Msk, /*!< Short between DOWN event and STOP task. */
NRF_LPCOMP_SHORT_READY_STOP_MASK = LPCOMP_SHORTS_READY_STOP_Msk, /*!< Short between READY event and STOP task. */
NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */
} nrf_lpcomp_short_mask_t;
/** @brief LPCOMP configuration. */
typedef struct
{
nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */
nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */
} nrf_lpcomp_config_t;
/** Default LPCOMP configuration. */
#define NRF_LPCOMP_CONFIG_DEFAULT { NRF_LPCOMP_REF_SUPPLY_FOUR_EIGHT, NRF_LPCOMP_DETECT_DOWN }
/**
* @brief Function for configuring LPCOMP.
*
* This function powers on LPCOMP and configures it. LPCOMP is in DISABLE state after configuration,
* so it must be enabled before using it. All shorts are inactive, events are cleared, and LPCOMP is stopped.
*
* @param[in] p_config Configuration.
*/
__STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config)
{
NRF_LPCOMP->TASKS_STOP = 1;
NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
NRF_LPCOMP->REFSEL =
(p_config->reference << LPCOMP_REFSEL_REFSEL_Pos) & LPCOMP_REFSEL_REFSEL_Msk;
//If external source is choosen extract analog reference index.
if ((p_config->reference & LPCOMP_REFSEL_REFSEL_ARef)==LPCOMP_REFSEL_REFSEL_ARef)
{
uint32_t extref = p_config->reference >> 16;
NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk;
}
NRF_LPCOMP->ANADETECT =
(p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk;
NRF_LPCOMP->SHORTS = 0;
NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk |
LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
}
/**
* @brief Function for selecting the LPCOMP input.
*
* This function selects the active input of LPCOMP.
*
* @param[in] input Input to be selected.
*/
__STATIC_INLINE void nrf_lpcomp_input_select(nrf_lpcomp_input_t input)
{
uint32_t lpcomp_enable_state = NRF_LPCOMP->ENABLE;
NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
NRF_LPCOMP->PSEL =
((uint32_t)input << LPCOMP_PSEL_PSEL_Pos) | (NRF_LPCOMP->PSEL & ~LPCOMP_PSEL_PSEL_Msk);
NRF_LPCOMP->ENABLE = lpcomp_enable_state;
}
/**
* @brief Function for enabling the Low Power Comparator.
*
* This function enables LPCOMP.
*
*/
__STATIC_INLINE void nrf_lpcomp_enable(void)
{
NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos;
NRF_LPCOMP->EVENTS_READY = 0;
NRF_LPCOMP->EVENTS_DOWN = 0;
NRF_LPCOMP->EVENTS_UP = 0;
NRF_LPCOMP->EVENTS_CROSS = 0;
}
/**
* @brief Function for disabling the Low Power Comparator.
*
* This function disables LPCOMP.
*
*/
__STATIC_INLINE void nrf_lpcomp_disable(void)
{
NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos;
}
/**
* @brief Function for getting the last LPCOMP compare result.
*
* @return The last compare result. If 0 then VIN+ < VIN-, if 1 then the opposite.
*/
__STATIC_INLINE uint32_t nrf_lpcomp_result_get(void)
{
return (uint32_t)NRF_LPCOMP->RESULT;
}
/**
* @brief Function for enabling interrupts from LPCOMP.
*
* @param[in] lpcomp_int_mask Mask of interrupts to be enabled.
*
* @sa nrf_lpcomp_int_disable()
* @sa nrf_lpcomp_int_enable_check()
*/
__STATIC_INLINE void nrf_lpcomp_int_enable(uint32_t lpcomp_int_mask)
{
NRF_LPCOMP->INTENSET = lpcomp_int_mask;
}
/**
* @brief Function for disabling interrupts from LPCOMP.
*
* @param[in] lpcomp_int_mask Mask of interrupts to be disabled.
*
* @sa nrf_lpcomp_int_enable()
* @sa nrf_lpcomp_int_enable_check()
*/
__STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask)
{
NRF_LPCOMP->INTENCLR = lpcomp_int_mask;
}
/**
* @brief Function for getting the enabled interrupts of LPCOMP.
*
* @param[in] lpcomp_int_mask Mask of interrupts to be checked.
*
* @retval true If any of interrupts of the specified mask are enabled.
*
* @sa nrf_lpcomp_int_enable()
* @sa nrf_lpcomp_int_disable()
*/
__STATIC_INLINE bool nrf_lpcomp_int_enable_check(uint32_t lpcomp_int_mask)
{
return (NRF_LPCOMP->INTENSET & lpcomp_int_mask); // when read this register will return the value of INTEN.
}
/**
* @brief Function for getting the address of a specific LPCOMP task register.
*
* @param[in] lpcomp_task LPCOMP task.
*
* @return The address of the specified LPCOMP task.
*/
__STATIC_INLINE uint32_t * nrf_lpcomp_task_address_get(nrf_lpcomp_task_t lpcomp_task)
{
return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_task);
}
/**
* @brief Function for getting the address of a specific LPCOMP event register.
*
* @param[in] lpcomp_event LPCOMP event.
*
* @return The address of the specified LPCOMP event.
*/
__STATIC_INLINE uint32_t * nrf_lpcomp_event_address_get(nrf_lpcomp_event_t lpcomp_event)
{
return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event);
}
/**
* @brief Function for setting LPCOMP shorts.
*
* @param[in] lpcomp_short_mask LPCOMP shorts by mask.
*
*/
__STATIC_INLINE void nrf_lpcomp_shorts_enable(uint32_t lpcomp_short_mask)
{
NRF_LPCOMP->SHORTS |= lpcomp_short_mask;
}
/**
* @brief Function for clearing LPCOMP shorts by mask.
*
* @param[in] lpcomp_short_mask LPCOMP shorts to be cleared.
*
*/
__STATIC_INLINE void nrf_lpcomp_shorts_disable(uint32_t lpcomp_short_mask)
{
NRF_LPCOMP->SHORTS &= ~lpcomp_short_mask;
}
/**
* @brief Function for setting a specific LPCOMP task.
*
* @param[in] lpcomp_task LPCOMP task to be set.
*
*/
__STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_task) ) = 1;
}
/**
* @brief Function for clearing a specific LPCOMP event.
*
* @param[in] lpcomp_event LPCOMP event to be cleared.
*
*/
__STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0;
}
/**
* @brief Function for getting the state of a specific LPCOMP event.
*
* @retval true If the specified LPCOMP event is active.
*
*/
__STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event)
{
return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event));
}
/**
*@}
**/
#endif /* NRF_LPCOMP_H_ */

View File

@ -0,0 +1,117 @@
/* Copyright (c) 2012 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.
*
* $LastChangedRevision: 17685 $
*/
/**
*@file
*@brief NMVC driver implementation
*/
#include <stdbool.h>
#include "nrf.h"
#include "nrf_nvmc.h"
void nrf_nvmc_page_erase(uint32_t address)
{
// Enable erase.
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
// Erase the page
NRF_NVMC->ERASEPAGE = address;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
}
void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
{
uint32_t byte_shift = address & (uint32_t)0x03;
uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in.
uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
value32 = value32 + ((uint32_t)value << (byte_shift << 3));
// Enable write.
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
*(uint32_t*)address32 = value32;
while(NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
{
}
}
void nrf_nvmc_write_word(uint32_t address, uint32_t value)
{
// Enable write.
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
}
*(uint32_t*)address = value;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
}
void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes)
{
uint32_t i;
for(i=0;i<num_bytes;i++)
{
nrf_nvmc_write_byte(address+i,src[i]);
}
}
void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words)
{
uint32_t i;
// Enable write.
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
for(i=0;i<num_words;i++)
{
((uint32_t*)address)[i] = src[i];
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
}
}

View File

@ -0,0 +1,90 @@
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential 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.
*
* $LastChangedRevision: 17685 $
*/
/**
* @file
* @brief NMVC driver API.
*/
#ifndef NRF_NVMC_H__
#define NRF_NVMC_H__
#include <stdint.h>
/**
* @defgroup nrf_nvmc Non-volatile memory controller
* @{
* @ingroup nrf_drivers
* @brief Driver for the NVMC peripheral.
*
* This driver allows writing to the non-volatile memory (NVM) regions
* of the chip. In order to write to NVM the controller must be powered
* on and the relevant page must be erased.
*
*/
/**
* @brief Erase a page in flash. This is required before writing to any
* address in the page.
*
* @param address Start address of the page.
*/
void nrf_nvmc_page_erase(uint32_t address);
/**
* @brief Write a single byte to flash.
*
* The function reads the word containing the byte, and then
* rewrites the entire word.
*
* @param address Address to write to.
* @param value Value to write.
*/
void nrf_nvmc_write_byte(uint32_t address , uint8_t value);
/**
* @brief Write a 32-bit word to flash.
* @param address Address to write to.
* @param value Value to write.
*/
void nrf_nvmc_write_word(uint32_t address, uint32_t value);
/**
* @brief Write consecutive bytes to flash.
*
* @param address Address to write to.
* @param src Pointer to data to copy from.
* @param num_bytes Number of bytes in src to write.
*/
void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes);
/**
* @brief Write consecutive words to flash.
*
* @param address Address to write to.
* @param src Pointer to data to copy from.
* @param num_words Number of bytes in src to write.
*/
void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words);
#endif // NRF_NVMC_H__
/** @} */

View File

@ -0,0 +1,359 @@
/* 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_PDM_H_
#define NRF_PDM_H_
/**
* @defgroup nrf_pdm_hal PDM HAL
* @{
* @ingroup nrf_pdm
*
* @brief @tagAPI52 Hardware abstraction layer for accessing the pulse density modulation (PDM) peripheral.
*/
#include <stdbool.h>
#include <stddef.h>
#include "nrf.h"
#include "nrf_assert.h"
#define NRF_PDM_GAIN_MINIMUM 0x00
#define NRF_PDM_GAIN_DEFAULT 0x28
#define NRF_PDM_GAIN_MAXIMUM 0x50
typedef uint8_t nrf_pdm_gain_t;
/**
* @brief PDM tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START), ///< Starts continuous PDM transfer.
NRF_PDM_TASK_STOP = offsetof(NRF_PDM_Type, TASKS_STOP) ///< Stops PDM transfer.
} nrf_pdm_task_t;
/**
* @brief PDM events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer has started.
NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer has finished.
NRF_PDM_EVENT_END = offsetof(NRF_PDM_Type, EVENTS_END) ///< The PDM has written the last sample specified by SAMPLE.MAXCNT (or the last sample after a STOP task has been received) to Data RAM.
} nrf_pdm_event_t;
/**
* @brief PDM interrupt masks.
*/
typedef enum
{
NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
NRF_PDM_INT_END = PDM_INTENSET_END_Msk ///< Interrupt on EVENTS_END event.
} nrf_pdm_int_mask_t;
/**
* @brief PDM clock frequency.
*/
typedef enum
{
NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K, ///< PDM_CLK = 1.000 MHz.
NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz.
NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K ///< PDM_CLK = 1.067 MHz.
} nrf_pdm_freq_t;
/**
* @brief PDM operation mode.
*/
typedef enum
{
NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo, ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word.
NRF_PDM_MODE_MONO = PDM_MODE_OPERATION_Mono ///< Sample and store two successive Left samples (16 bit each) per RAM word.
} nrf_pdm_mode_t;
/**
* @brief PDM sampling mode.
*/
typedef enum
{
NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling, ///< Left (or mono) is sampled on falling edge of PDM_CLK.
NRF_PDM_EDGE_LEFTRISING = PDM_MODE_EDGE_LeftRising ///< Left (or mono) is sampled on rising edge of PDM_CLK.
} nrf_pdm_edge_t;
/**
* @brief Function for triggering a PDM task.
*
* @param[in] pdm_task PDM task.
*/
__STATIC_INLINE void nrf_pdm_task_trigger(nrf_pdm_task_t pdm_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_task)) = 0x1UL;
}
/**
* @brief Function for getting the address of a PDM task register.
*
* @param[in] pdm_task PDM task.
*
* @return Address of the specified PDM task.
*/
__STATIC_INLINE uint32_t nrf_pdm_task_address_get(nrf_pdm_task_t pdm_task)
{
return (uint32_t)((uint8_t *)NRF_PDM + (uint32_t)pdm_task);
}
/**
* @brief Function for getting the state of a PDM event.
*
* @param[in] pdm_event PDM event.
*
* @return State of the specified PDM event.
*/
__STATIC_INLINE bool nrf_pdm_event_check(nrf_pdm_event_t pdm_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event);
}
/**
* @brief Function for clearing a PDM event.
*
* @param[in] pdm_event PDM event.
*/
__STATIC_INLINE void nrf_pdm_event_clear(nrf_pdm_event_t pdm_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)) = 0x0UL;
}
/**
* @brief Function for getting the address of a PDM event register.
*
* @param[in] pdm_event PDM event.
*
* @return Address of the specified PDM event.
*/
__STATIC_INLINE volatile uint32_t * nrf_pdm_event_address_get(nrf_pdm_event_t pdm_event)
{
return (volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event);
}
/**
* @brief Function for enabling PDM interrupts.
*
* @param[in] pdm_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_pdm_int_enable(uint32_t pdm_int_mask)
{
NRF_PDM->INTENSET = pdm_int_mask;
}
/**
* @brief Function for retrieving the state of PDM interrupts.
*
* @param[in] pdm_int_mask Interrupts 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_pdm_int_enable_check(uint32_t pdm_int_mask)
{
return (bool)(NRF_PDM->INTENSET & pdm_int_mask);
}
/**
* @brief Function for disabling interrupts.
*
* @param pdm_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_pdm_int_disable(uint32_t pdm_int_mask)
{
NRF_PDM->INTENCLR = pdm_int_mask;
}
/**
* @brief Function for enabling the PDM peripheral.
*
* The PDM peripheral must be enabled before use.
*/
__STATIC_INLINE void nrf_pdm_enable(void)
{
NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos);
}
/**
* @brief Function for disabling the PDM peripheral.
*/
__STATIC_INLINE void nrf_pdm_disable(void)
{
NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos);
}
/**
* @brief Function for checking if the PDM peripheral is enabled.
*
* @retval true If the PDM peripheral is enabled.
* @retval false If the PDM peripheral is not enabled.
*/
__STATIC_INLINE bool nrf_pdm_enable_check(void)
{
return (NRF_PDM->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos));
}
/**
* @brief Function for setting the PDM operation mode.
*
* @param[in] pdm_mode PDM operation mode.
* @param[in] pdm_edge PDM sampling mode.
*/
__STATIC_INLINE void nrf_pdm_mode_set(nrf_pdm_mode_t pdm_mode, nrf_pdm_edge_t pdm_edge)
{
NRF_PDM->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk)
| ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk);
}
/**
* @brief Function for getting the PDM operation mode.
*
* @param[out] p_pdm_mode PDM operation mode.
* @param[out] p_pdm_edge PDM sampling mode.
*/
__STATIC_INLINE void nrf_pdm_mode_get(nrf_pdm_mode_t * p_pdm_mode, nrf_pdm_edge_t * p_pdm_edge)
{
uint32_t mode = NRF_PDM->MODE;
*p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos);
*p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos);
}
/**
* @brief Function for setting the PDM clock frequency.
*
* @param[in] pdm_freq PDM clock frequency.
*/
__STATIC_INLINE void nrf_pdm_clock_set(nrf_pdm_freq_t pdm_freq)
{
NRF_PDM->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk);
}
/**
* @brief Function for getting the PDM clock frequency.
*/
__STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(void)
{
return (nrf_pdm_freq_t) ((NRF_PDM->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk);
}
/**
* @brief Function for setting up the PDM pins.
*
* @param[in] psel_clk CLK pin number.
* @param[in] psel_din DIN pin number.
*/
__STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din)
{
NRF_PDM->PSEL.CLK = ((psel_clk << PDM_PSEL_CLK_PIN_Pos) & PDM_PSEL_CLK_PIN_Msk)
| ((PDM_PSEL_CLK_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_CLK_CONNECT_Msk);
NRF_PDM->PSEL.DIN = ((psel_din << PDM_PSEL_DIN_PIN_Pos) & PDM_PSEL_DIN_PIN_Msk)
| ((PDM_PSEL_DIN_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_DIN_CONNECT_Msk);
}
/**
* @brief Function for disconnecting the PDM pins.
*/
__STATIC_INLINE void nrf_pdm_psel_disconnect()
{
NRF_PDM->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos)
& PDM_PSEL_CLK_CONNECT_Msk);
NRF_PDM->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos)
& PDM_PSEL_DIN_CONNECT_Msk);
}
/**
* @brief Function for setting the PDM gain.
*
* @param[in] gain_l Left channel gain.
* @param[in] gain_r Right channel gain.
*/
__STATIC_INLINE void nrf_pdm_gain_set(nrf_pdm_gain_t gain_l, nrf_pdm_gain_t gain_r)
{
NRF_PDM->GAINL = gain_l;
NRF_PDM->GAINR = gain_r;
}
/**
* @brief Function for getting the PDM gain.
*
* @param[out] p_gain_l Left channel gain.
* @param[out] p_gain_r Right channel gain.
*/
__STATIC_INLINE void nrf_pdm_gain_get(nrf_pdm_gain_t * p_gain_l, nrf_pdm_gain_t * p_gain_r)
{
*p_gain_l = NRF_PDM->GAINL;
*p_gain_r = NRF_PDM->GAINR;
}
/**
* @brief Function for setting the PDM sample buffer.
*
* @param[in] p_buffer Pointer to the RAM address where samples should be written with EasyDMA.
* @param[in] num Number of samples to allocate memory for in EasyDMA mode.
*
* The amount of allocated RAM depends on the operation mode.
* - For stereo mode: N 32-bit words.
* - For mono mode: Ceil(N/2) 32-bit words.
*/
__STATIC_INLINE void nrf_pdm_buffer_set(uint32_t * p_buffer, uint32_t num)
{
NRF_PDM->SAMPLE.PTR = (uint32_t)p_buffer;
NRF_PDM->SAMPLE.MAXCNT = num;
}
/**
* @brief Function for getting the current PDM sample buffer address.
*
* @return Pointer to the current sample buffer.
*/
__STATIC_INLINE uint32_t * nrf_pdm_buffer_get()
{
return (uint32_t *)NRF_PDM->SAMPLE.PTR;
}
/**
*@}
**/
#endif /* NRF_PDM_H_ */

View File

@ -0,0 +1,402 @@
/* 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_PPI_H__
#define NRF_PPI_H__
#include <stddef.h>
#include "nrf.h"
/**
* @defgroup nrf_ppi_hal PPI HAL
* @{
* @ingroup nrf_ppi
* @brief Hardware access layer for setting up Programmable Peripheral Interconnect (PPI) channels.
*/
#define NRF_PPI_TASK_SET (1UL)
/**
* @enum nrf_ppi_channel_t
* @brief PPI channels.
*/
typedef enum
{
NRF_PPI_CHANNEL0 = PPI_CHEN_CH0_Pos, /**< Channel 0. */
NRF_PPI_CHANNEL1 = PPI_CHEN_CH1_Pos, /**< Channel 1. */
NRF_PPI_CHANNEL2 = PPI_CHEN_CH2_Pos, /**< Channel 2. */
NRF_PPI_CHANNEL3 = PPI_CHEN_CH3_Pos, /**< Channel 3. */
NRF_PPI_CHANNEL4 = PPI_CHEN_CH4_Pos, /**< Channel 4. */
NRF_PPI_CHANNEL5 = PPI_CHEN_CH5_Pos, /**< Channel 5. */
NRF_PPI_CHANNEL6 = PPI_CHEN_CH6_Pos, /**< Channel 6. */
NRF_PPI_CHANNEL7 = PPI_CHEN_CH7_Pos, /**< Channel 7. */
NRF_PPI_CHANNEL8 = PPI_CHEN_CH8_Pos, /**< Channel 8. */
NRF_PPI_CHANNEL9 = PPI_CHEN_CH9_Pos, /**< Channel 9. */
NRF_PPI_CHANNEL10 = PPI_CHEN_CH10_Pos, /**< Channel 10. */
NRF_PPI_CHANNEL11 = PPI_CHEN_CH11_Pos, /**< Channel 11. */
NRF_PPI_CHANNEL12 = PPI_CHEN_CH12_Pos, /**< Channel 12. */
NRF_PPI_CHANNEL13 = PPI_CHEN_CH13_Pos, /**< Channel 13. */
NRF_PPI_CHANNEL14 = PPI_CHEN_CH14_Pos, /**< Channel 14. */
NRF_PPI_CHANNEL15 = PPI_CHEN_CH15_Pos, /**< Channel 15. */
#ifdef NRF52
NRF_PPI_CHANNEL16 = PPI_CHEN_CH16_Pos, /**< Channel 16. */
NRF_PPI_CHANNEL17 = PPI_CHEN_CH17_Pos, /**< Channel 17. */
NRF_PPI_CHANNEL18 = PPI_CHEN_CH18_Pos, /**< Channel 18. */
NRF_PPI_CHANNEL19 = PPI_CHEN_CH19_Pos, /**< Channel 19. */
#endif
NRF_PPI_CHANNEL20 = PPI_CHEN_CH20_Pos, /**< Channel 20. */
NRF_PPI_CHANNEL21 = PPI_CHEN_CH21_Pos, /**< Channel 21. */
NRF_PPI_CHANNEL22 = PPI_CHEN_CH22_Pos, /**< Channel 22. */
NRF_PPI_CHANNEL23 = PPI_CHEN_CH23_Pos, /**< Channel 23. */
NRF_PPI_CHANNEL24 = PPI_CHEN_CH24_Pos, /**< Channel 24. */
NRF_PPI_CHANNEL25 = PPI_CHEN_CH25_Pos, /**< Channel 25. */
NRF_PPI_CHANNEL26 = PPI_CHEN_CH26_Pos, /**< Channel 26. */
NRF_PPI_CHANNEL27 = PPI_CHEN_CH27_Pos, /**< Channel 27. */
NRF_PPI_CHANNEL28 = PPI_CHEN_CH28_Pos, /**< Channel 28. */
NRF_PPI_CHANNEL29 = PPI_CHEN_CH29_Pos, /**< Channel 29. */
NRF_PPI_CHANNEL30 = PPI_CHEN_CH30_Pos, /**< Channel 30. */
NRF_PPI_CHANNEL31 = PPI_CHEN_CH31_Pos /**< Channel 31. */
} nrf_ppi_channel_t;
/**
* @enum nrf_ppi_channel_group_t
* @brief PPI channel groups.
*/
typedef enum
{
NRF_PPI_CHANNEL_GROUP0 = 0, /**< Channel group 0. */
NRF_PPI_CHANNEL_GROUP1 = 1, /**< Channel group 1. */
NRF_PPI_CHANNEL_GROUP2 = 2, /**< Channel group 2. */
NRF_PPI_CHANNEL_GROUP3 = 3, /**< Channel group 3. */
#ifdef NRF52
NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */
NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */
#endif
} nrf_ppi_channel_group_t;
/**
* @enum nrf_ppi_channel_include_t
* @brief Definition of which PPI channels belong to a group.
*/
typedef enum
{
NRF_PPI_CHANNEL_EXCLUDE = PPI_CHG_CH0_Excluded, /**< Channel excluded from a group. */
NRF_PPI_CHANNEL_INCLUDE = PPI_CHG_CH0_Included /**< Channel included in a group. */
} nrf_ppi_channel_include_t;
/**
* @enum nrf_ppi_channel_enable_t
* @brief Definition if a PPI channel is enabled.
*/
typedef enum
{
NRF_PPI_CHANNEL_DISABLED = PPI_CHEN_CH0_Disabled, /**< Channel disabled. */
NRF_PPI_CHANNEL_ENABLED = PPI_CHEN_CH0_Enabled /**< Channel enabled. */
} nrf_ppi_channel_enable_t;
/**
* @enum nrf_ppi_task_t
* @brief PPI tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_PPI_TASK_CHG0_EN = offsetof(NRF_PPI_Type, TASKS_CHG[0].EN), /**< Task for enabling channel group 0 */
NRF_PPI_TASK_CHG0_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[0].DIS), /**< Task for disabling channel group 0 */
NRF_PPI_TASK_CHG1_EN = offsetof(NRF_PPI_Type, TASKS_CHG[1].EN), /**< Task for enabling channel group 1 */
NRF_PPI_TASK_CHG1_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[1].DIS), /**< Task for disabling channel group 1 */
NRF_PPI_TASK_CHG2_EN = offsetof(NRF_PPI_Type, TASKS_CHG[2].EN), /**< Task for enabling channel group 2 */
NRF_PPI_TASK_CHG2_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[2].DIS), /**< Task for disabling channel group 2 */
NRF_PPI_TASK_CHG3_EN = offsetof(NRF_PPI_Type, TASKS_CHG[3].EN), /**< Task for enabling channel group 3 */
NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS), /**< Task for disabling channel group 3 */
#ifdef NRF52
NRF_PPI_TASK_CHG4_EN = offsetof(NRF_PPI_Type, TASKS_CHG[4].EN), /**< Task for enabling channel group 4 */
NRF_PPI_TASK_CHG4_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[4].DIS), /**< Task for disabling channel group 4 */
NRF_PPI_TASK_CHG5_EN = offsetof(NRF_PPI_Type, TASKS_CHG[5].EN), /**< Task for enabling channel group 5 */
NRF_PPI_TASK_CHG5_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[5].DIS) /**< Task for disabling channel group 5 */
#endif
/*lint -restore*/
} nrf_ppi_task_t;
/**
* @brief Function for enabling a given PPI channel.
*
* @details This function enables only one channel.
*
* @param[in] channel Channel to enable.
*
* */
__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Set << ((uint32_t) channel);
}
/**
* @brief Function for disabling a given PPI channel.
*
* @details This function disables only one channel.
*
* @param[in] channel Channel to disable.
*/
__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Clear << ((uint32_t) channel);
}
/**
* @brief Function for checking if a given PPI channel is enabled.
*
* @details This function checks only one channel.
*
* @param[in] channel Channel to check.
*
* @retval NRF_PPI_CHANNEL_ENABLED If the channel is enabled.
* @retval NRF_PPI_CHANNEL_DISABLED If the channel is not enabled.
*
*/
__STATIC_INLINE nrf_ppi_channel_enable_t nrf_ppi_channel_enable_get(nrf_ppi_channel_t channel)
{
if (NRF_PPI->CHEN & (PPI_CHEN_CH0_Msk << ((uint32_t) channel)))
{
return NRF_PPI_CHANNEL_ENABLED;
}
else
{
return NRF_PPI_CHANNEL_DISABLED;
}
}
/**
* @brief Function for disabling all PPI channels.
*/
__STATIC_INLINE void nrf_ppi_channel_disable_all(void)
{
NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL);
}
/**
* @brief Function for disabling multiple PPI channels.
*
* @param[in] mask Channel mask.
*/
__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask)
{
NRF_PPI->CHENCLR = mask;
}
/**
* @brief Function for setting up event and task endpoints for a given PPI channel.
*
* @param[in] eep Event register address.
*
* @param[in] tep Task register address.
*
* @param[in] channel Channel to which the given endpoints are assigned.
*/
__STATIC_INLINE void nrf_ppi_channel_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep,
uint32_t tep)
{
NRF_PPI->CH[(uint32_t) channel].EEP = eep;
NRF_PPI->CH[(uint32_t) channel].TEP = tep;
}
#ifdef NRF52
/**
* @brief Function for setting up task endpoint for a given PPI fork.
*
* @param[in] fork_tep Task register address.
*
* @param[in] channel Channel to which the given fork endpoint is assigned.
*/
__STATIC_INLINE void nrf_ppi_fork_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t fork_tep)
{
NRF_PPI->FORK[(uint32_t) channel].TEP = fork_tep;
}
/**
* @brief Function for setting up event and task endpoints for a given PPI channel and fork.
*
* @param[in] eep Event register address.
*
* @param[in] tep Task register address.
*
* @param[in] fork_tep Fork task register address (register value).
*
* @param[in] channel Channel to which the given endpoints are assigned.
*/
__STATIC_INLINE void nrf_ppi_channel_and_fork_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep,
uint32_t tep,
uint32_t fork_tep)
{
nrf_ppi_channel_endpoint_setup(channel, eep, tep);
nrf_ppi_fork_endpoint_setup(channel, fork_tep);
}
#endif
/**
* @brief Function for including a PPI channel in a channel group.
*
* @details This function adds only one channel to the group.
*
* @param[in] channel Channel to be included in the group.
*
* @param[in] channel_group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channel_include_in_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] | (PPI_CHG_CH0_Included << ((uint32_t) channel));
}
/**
* @brief Function for including multiple PPI channels in a channel group.
*
* @details This function adds all specified channels to the group.
*
* @param[in] channel_mask Channels to be included in the group.
*
* @param[in] channel_group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channels_include_in_group(uint32_t channel_mask,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] | (channel_mask);
}
/**
* @brief Function for removing a PPI channel from a channel group.
*
* @details This function removes only one channel from the group.
*
* @param[in] channel Channel to be removed from the group.
*
* @param[in] channel_group Channel group.
*/
__STATIC_INLINE void nrf_ppi_channel_remove_from_group(nrf_ppi_channel_t channel,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] & ~(PPI_CHG_CH0_Included << ((uint32_t) channel));
}
/**
* @brief Function for removing multiple PPI channels from a channel group.
*
* @details This function removes all specified channels from the group.
*
* @param[in] channel_mask Channels to be removed from the group.
*
* @param[in] channel_group Channel group.
*/
__STATIC_INLINE void nrf_ppi_channels_remove_from_group(uint32_t channel_mask,
nrf_ppi_channel_group_t channel_group)
{
NRF_PPI->CHG[(uint32_t) channel_group] =
NRF_PPI->CHG[(uint32_t) channel_group] & ~(channel_mask);
}
/**
* @brief Function for removing all PPI channels from a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_channel_group_clear(nrf_ppi_channel_group_t group)
{
NRF_PPI->CHG[(uint32_t) group] = 0;
}
/**
* @brief Function for enabling a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_group_enable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].EN = NRF_PPI_TASK_SET;
}
/**
* @brief Function for disabling a channel group.
*
* @param[in] group Channel group.
*
*/
__STATIC_INLINE void nrf_ppi_group_disable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].DIS = NRF_PPI_TASK_SET;
}
/**
* @brief Function for setting a PPI task.
*
* @param[in] ppi_task PPI task to set.
*/
__STATIC_INLINE void nrf_ppi_task_trigger(nrf_ppi_task_t ppi_task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task)) = NRF_PPI_TASK_SET;
}
/**
* @brief Function for returning the address of a specific PPI task register.
*
* @param[in] ppi_task PPI task.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_address_get(nrf_ppi_task_t ppi_task)
{
return (uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task);
}
/**
* @brief Function for returning the PPI enable task address of a specific group.
*
* @param[in] group PPI group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_enable_address_get(nrf_ppi_channel_group_t group)
{
return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].EN;
}
/**
* @brief Function for returning the PPI disable task address of a specific group.
*
* @param[in] group PPI group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channel_group_t group)
{
return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].DIS;
}
/**
*@}
**/
/*lint --flb "Leave library region" */
#endif // NRF_PPI_H__

View File

@ -0,0 +1,661 @@
/* 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.
*
*/
/**
* @defgroup nrf_pwm_hal PWM HAL
* @{
* @ingroup nrf_pwm
*
* @brief @tagAPI52 Hardware access layer for managing the Pulse Width Modulation (PWM)
* peripheral.
*/
#ifndef NRF_PWM_H__
#define NRF_PWM_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_assert.h"
/**
* @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set
* function call to specify that a given output channel shall not be
* connected to a physical pin.
*/
#define NRF_PWM_PIN_NOT_CONNECTED 0xFFFFFFFF
/**
* @brief Number of channels in each PWM instance.
*/
#define NRF_PWM_CHANNEL_COUNT 4
/**
* @brief PWM tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_PWM_TASK_STOP = offsetof(NRF_PWM_Type, TASKS_STOP), ///< Stops PWM pulse generation on all channels at the end of the current PWM period, and stops the sequence playback.
NRF_PWM_TASK_SEQSTART0 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[0]), ///< Starts playback of sequence 0.
NRF_PWM_TASK_SEQSTART1 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[1]), ///< Starts playback of sequence 1.
NRF_PWM_TASK_NEXTSTEP = offsetof(NRF_PWM_Type, TASKS_NEXTSTEP) ///< Steps by one value in the current sequence if the decoder is set to @ref NRF_PWM_STEP_TRIGGERED mode.
/*lint -restore*/
} nrf_pwm_task_t;
/**
* @brief PWM events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_PWM_EVENT_STOPPED = offsetof(NRF_PWM_Type, EVENTS_STOPPED), ///< Response to STOP task, emitted when PWM pulses are no longer generated.
NRF_PWM_EVENT_SEQSTARTED0 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[0]), ///< First PWM period started on sequence 0.
NRF_PWM_EVENT_SEQSTARTED1 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[1]), ///< First PWM period started on sequence 1.
NRF_PWM_EVENT_SEQEND0 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[0]), ///< Emitted at the end of every sequence 0 when its last value has been read from RAM.
NRF_PWM_EVENT_SEQEND1 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[1]), ///< Emitted at the end of every sequence 1 when its last value has been read from RAM.
NRF_PWM_EVENT_PWMPERIODEND = offsetof(NRF_PWM_Type, EVENTS_PWMPERIODEND), ///< Emitted at the end of each PWM period.
NRF_PWM_EVENT_LOOPSDONE = offsetof(NRF_PWM_Type, EVENTS_LOOPSDONE) ///< Concatenated sequences have been played the requested number of times.
/*lint -restore*/
} nrf_pwm_event_t;
/**
* @brief PWM interrupts.
*/
typedef enum
{
NRF_PWM_INT_STOPPED_MASK = PWM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
NRF_PWM_INT_SEQSTARTED0_MASK = PWM_INTENSET_SEQSTARTED0_Msk, ///< Interrupt on SEQSTARTED[0] event.
NRF_PWM_INT_SEQSTARTED1_MASK = PWM_INTENSET_SEQSTARTED1_Msk, ///< Interrupt on SEQSTARTED[1] event.
NRF_PWM_INT_SEQEND0_MASK = PWM_INTENSET_SEQEND0_Msk, ///< Interrupt on SEQEND[0] event.
NRF_PWM_INT_SEQEND1_MASK = PWM_INTENSET_SEQEND1_Msk, ///< Interrupt on SEQEND[1] event.
NRF_PWM_INT_PWMPERIODEND_MASK = PWM_INTENSET_PWMPERIODEND_Msk, ///< Interrupt on PWMPERIODEND event.
NRF_PWM_INT_LOOPSDONE_MASK = PWM_INTENSET_LOOPSDONE_Msk ///< Interrupt on LOOPSDONE event.
} nrf_pwm_int_mask_t;
/**
* @brief PWM shortcuts.
*/
typedef enum
{
NRF_PWM_SHORT_SEQEND0_STOP_MASK = PWM_SHORTS_SEQEND0_STOP_Msk, ///< Shortcut between SEQEND[0] event and STOP task.
NRF_PWM_SHORT_SEQEND1_STOP_MASK = PWM_SHORTS_SEQEND1_STOP_Msk, ///< Shortcut between SEQEND[1] event and STOP task.
NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[0] task.
NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[1] task.
NRF_PWM_SHORT_LOOPSDONE_STOP_MASK = PWM_SHORTS_LOOPSDONE_STOP_Msk ///< Shortcut between LOOPSDONE event and STOP task.
} nrf_pwm_short_mask_t;
/**
* @brief PWM modes of operation.
*/
typedef enum
{
NRF_PWM_MODE_UP = PWM_MODE_UPDOWN_Up, ///< Up counter (edge-aligned PWM duty cycle).
NRF_PWM_MODE_UP_AND_DOWN = PWM_MODE_UPDOWN_UpAndDown, ///< Up and down counter (center-aligned PWM duty cycle).
} nrf_pwm_mode_t;
/**
* @brief PWM base clock frequencies.
*/
typedef enum
{
NRF_PWM_CLK_16MHz = PWM_PRESCALER_PRESCALER_DIV_1, ///< 16 MHz / 1 = 16 MHz.
NRF_PWM_CLK_8MHz = PWM_PRESCALER_PRESCALER_DIV_2, ///< 16 MHz / 2 = 8 MHz.
NRF_PWM_CLK_4MHz = PWM_PRESCALER_PRESCALER_DIV_4, ///< 16 MHz / 4 = 4 MHz.
NRF_PWM_CLK_2MHz = PWM_PRESCALER_PRESCALER_DIV_8, ///< 16 MHz / 8 = 2 MHz.
NRF_PWM_CLK_1MHz = PWM_PRESCALER_PRESCALER_DIV_16, ///< 16 MHz / 16 = 1 MHz.
NRF_PWM_CLK_500kHz = PWM_PRESCALER_PRESCALER_DIV_32, ///< 16 MHz / 32 = 500 kHz.
NRF_PWM_CLK_250kHz = PWM_PRESCALER_PRESCALER_DIV_64, ///< 16 MHz / 64 = 250 kHz.
NRF_PWM_CLK_125kHz = PWM_PRESCALER_PRESCALER_DIV_128 ///< 16 MHz / 128 = 125 kHz.
} nrf_pwm_clk_t;
/**
* @brief PWM decoder load modes.
*
* The selected mode determines how the sequence data is read from RAM and
* spread to the compare registers.
*/
typedef enum
{
NRF_PWM_LOAD_COMMON = PWM_DECODER_LOAD_Common, ///< 1st half word (16-bit) used in all PWM channels (0-3).
NRF_PWM_LOAD_GROUPED = PWM_DECODER_LOAD_Grouped, ///< 1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3.
NRF_PWM_LOAD_INDIVIDUAL = PWM_DECODER_LOAD_Individual, ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3.
NRF_PWM_LOAD_WAVE_FORM = PWM_DECODER_LOAD_WaveForm ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter.
} nrf_pwm_dec_load_t;
/**
* @brief PWM decoder next step modes.
*
* The selected mode determines when the next value from the active sequence
* is loaded.
*/
typedef enum
{
NRF_PWM_STEP_AUTO = PWM_DECODER_MODE_RefreshCount, ///< Automatically after the current value is played and repeated the requested number of times.
NRF_PWM_STEP_TRIGGERED = PWM_DECODER_MODE_NextStep ///< When the @ref NRF_PWM_TASK_NEXTSTEP task is triggered.
} nrf_pwm_dec_step_t;
/**
* @brief Type used for defining duty cycle values for a sequence
* loaded in @ref NRF_PWM_LOAD_COMMON mode.
*/
typedef uint16_t nrf_pwm_values_common_t;
/**
* @brief Structure for defining duty cycle values for a sequence
* loaded in @ref NRF_PWM_LOAD_GROUPED mode.
*/
typedef struct {
uint16_t group_0; ///< Duty cycle value for group 0 (channels 0 and 1).
uint16_t group_1; ///< Duty cycle value for group 1 (channels 2 and 3).
} nrf_pwm_values_grouped_t;
/**
* @brief Structure for defining duty cycle values for a sequence
* loaded in @ref NRF_PWM_LOAD_INDIVIDUAL mode.
*/
typedef struct
{
uint16_t channel_0; ///< Duty cycle value for channel 0.
uint16_t channel_1; ///< Duty cycle value for channel 1.
uint16_t channel_2; ///< Duty cycle value for channel 2.
uint16_t channel_3; ///< Duty cycle value for channel 3.
} nrf_pwm_values_individual_t;
/**
* @brief Structure for defining duty cycle values for a sequence
* loaded in @ref NRF_PWM_LOAD_WAVE_FORM mode.
*/
typedef struct {
uint16_t channel_0; ///< Duty cycle value for channel 0.
uint16_t channel_1; ///< Duty cycle value for channel 1.
uint16_t channel_2; ///< Duty cycle value for channel 2.
uint16_t counter_top; ///< Top value for the pulse generator counter.
} nrf_pwm_values_wave_form_t;
/**
* @brief Union grouping pointers to arrays of duty cycle values applicable to
* various loading modes.
*/
typedef union {
nrf_pwm_values_common_t const * p_common; ///< Pointer to be used in @ref NRF_PWM_LOAD_COMMON mode.
nrf_pwm_values_grouped_t const * p_grouped; ///< Pointer to be used in @ref NRF_PWM_LOAD_GROUPED mode.
nrf_pwm_values_individual_t const * p_individual; ///< Pointer to be used in @ref NRF_PWM_LOAD_INDIVIDUAL mode.
nrf_pwm_values_wave_form_t const * p_wave_form; ///< Pointer to be used in @ref NRF_PWM_LOAD_WAVE_FORM mode.
uint16_t const * p_raw; ///< Pointer providing raw access to the values.
} nrf_pwm_values_t;
/**
* @brief Structure for defining a sequence of PWM duty cycles.
*
* When the sequence is set (by a call to @ref nrf_pwm_sequence_set), the
* provided duty cycle values are not copied. The @p values pointer is stored
* in the peripheral's internal register, and the values are loaded from RAM
* during the sequence playback. Therefore, you must ensure that the values
* do not change before and during the sequence playback (for example,
* the values cannot be placed in a local variable that is allocated on stack).
* If the sequence is played in a loop and the values should be updated
* before the next iteration, it is safe to modify them when the corresponding
* event signaling the end of sequence occurs (@ref NRF_PWM_EVENT_SEQEND0
* or @ref NRF_PWM_EVENT_SEQEND1, respectively).
*
* @note The @p repeats and @p end_delay values (which are written to the
* SEQ[n].REFRESH and SEQ[n].ENDDELAY registers in the peripheral,
* respectively) are ignored at the end of a complex sequence
* playback, indicated by the LOOPSDONE event.
* See the @linkProductSpecification52 for more information.
*/
typedef struct
{
nrf_pwm_values_t values; ///< Pointer to an array with duty cycle values. This array must be in Data RAM.
/**< This field is defined as an union of pointers
* to provide a convenient way to define duty
* cycle values in various loading modes
* (see @ref nrf_pwm_dec_load_t).
* In each value, the most significant bit (15)
* determines the polarity of the output and the
* others (14-0) compose the 15-bit value to be
* compared with the pulse generator counter. */
uint16_t length; ///< Number of 16-bit values in the array pointed by @p values.
uint32_t repeats; ///< Number of times that each duty cycle should be repeated (after being played once). Ignored in @ref NRF_PWM_STEP_TRIGGERED mode.
uint32_t end_delay; ///< Additional time (in PWM periods) that the last duty cycle is to be kept after the sequence is played. Ignored in @ref NRF_PWM_STEP_TRIGGERED mode.
} nrf_pwm_sequence_t;
/**
* @brief Helper macro for calculating the number of 16-bit values in specified
* array of duty cycle values.
*/
#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array)/sizeof(uint16_t))
/**
* @brief Function for activating a specific PWM task.
*
* @param[in] p_pwm PWM instance.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_pwm,
nrf_pwm_task_t task);
/**
* @brief Function for getting the address of a specific PWM task register.
*
* @param[in] p_pwm PWM instance.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_pwm,
nrf_pwm_task_t task);
/**
* @brief Function for clearing a specific PWM event.
*
* @param[in] p_pwm PWM instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_pwm,
nrf_pwm_event_t event);
/**
* @brief Function for checking the state of a specific PWM event.
*
* @param[in] p_pwm PWM instance.
* @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_pwm_event_check(NRF_PWM_Type const * p_pwm,
nrf_pwm_event_t event);
/**
* @brief Function for getting the address of a specific PWM event register.
*
* @param[in] p_pwm PWM instance.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_pwm,
nrf_pwm_event_t event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask);
/**
* @brief Function for setting the configuration of PWM shortcuts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_shorts_mask Shortcuts configuration to set.
*/
__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask);
/**
* @brief Function for setting the configuration of PWM interrupts.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_int_mask Interrupts configuration to set.
*/
__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_pwm PWM instance.
* @param[in] pwm_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_pwm,
nrf_pwm_int_mask_t pwm_int);
/**
* @brief Function for enabling the PWM peripheral.
*
* @param[in] p_pwm PWM instance.
*/
__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_pwm);
/**
* @brief Function for disabling the PWM peripheral.
*
* @param[in] p_pwm PWM instance.
*/
__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_pwm);
/**
* @brief Function for assigning pins to PWM output channels.
*
* Usage of all PWM output channels is optional. If a given channel is not
* needed, pass the @ref NRF_PWM_PIN_NOT_CONNECTED value instead of its pin
* number.
*
* @param[in] p_pwm PWM instance.
* @param[in] out_pins Array with pin numbers for individual PWM output channels.
*/
__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_pwm,
uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]);
/**
* @brief Function for configuring the PWM peripheral.
*
* @param[in] p_pwm PWM instance.
* @param[in] base_clock Base clock frequency.
* @param[in] mode Operating mode of the pulse generator counter.
* @param[in] top_value Value up to which the pulse generator counter counts.
*/
__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm,
nrf_pwm_clk_t base_clock,
nrf_pwm_mode_t mode,
uint16_t top_value);
/**
* @brief Function for defining a sequence of PWM duty cycles.
*
* @param[in] p_pwm PWM instance.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] p_seq Pointer to the sequence definition.
*/
__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_seq);
/**
* @brief Function for modifying the pointer to the duty cycle values
* in the specified sequence.
*
* @param[in] p_pwm PWM instance.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] p_values Pointer to an array with duty cycle values.
*/
__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint16_t const * p_values);
/**
* @brief Function for modifying the total number of duty cycle values
* in the specified sequence.
*
* @param[in] p_pwm PWM instance.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] length Number of duty cycle values.
*/
__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint16_t length);
/**
* @brief Function for modifying the additional number of PWM periods spent
* on each duty cycle value in the specified sequence.
*
* @param[in] p_pwm PWM instance.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] refresh Number of additional PWM periods for each duty cycle value.
*/
__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint32_t refresh);
/**
* @brief Function for modifying the additional time added after the sequence
* is played.
*
* @param[in] p_pwm PWM instance.
* @param[in] seq_id Identifier of the sequence (0 or 1).
* @param[in] end_delay Number of PWM periods added at the end of the sequence.
*/
__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint32_t end_delay);
/**
* @brief Function for setting the mode of loading sequence data from RAM
* and advancing the sequence.
*
* @param[in] p_pwm PWM instance.
* @param[in] dec_load Mode of loading sequence data from RAM.
* @param[in] dec_step Mode of advancing the active sequence.
*/
__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_pwm,
nrf_pwm_dec_load_t dec_load,
nrf_pwm_dec_step_t dec_step);
/**
* @brief Function for setting the number of times the sequence playback
* should be performed.
*
* This function applies to two-sequence playback (concatenated sequence 0 and 1).
* A single sequence can be played back only once.
*
* @param[in] p_pwm PWM instance.
* @param[in] loop_count Number of times to perform the sequence playback.
*/
__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_pwm,
uint16_t loop_count);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_pwm,
nrf_pwm_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_pwm,
nrf_pwm_task_t task)
{
return ((uint32_t)p_pwm + (uint32_t)task);
}
__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_pwm,
nrf_pwm_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_pwm,
nrf_pwm_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_pwm,
nrf_pwm_event_t event)
{
return ((uint32_t)p_pwm + (uint32_t)event);
}
__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask)
{
p_pwm->SHORTS |= pwm_shorts_mask;
}
__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask)
{
p_pwm->SHORTS &= ~(pwm_shorts_mask);
}
__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_pwm,
uint32_t pwm_shorts_mask)
{
p_pwm->SHORTS = pwm_shorts_mask;
}
__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask)
{
p_pwm->INTENSET = pwm_int_mask;
}
__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask)
{
p_pwm->INTENCLR = pwm_int_mask;
}
__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_pwm,
uint32_t pwm_int_mask)
{
p_pwm->INTEN = pwm_int_mask;
}
__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_pwm,
nrf_pwm_int_mask_t pwm_int)
{
return (bool)(p_pwm->INTENSET & pwm_int);
}
__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_pwm)
{
p_pwm->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_pwm)
{
p_pwm->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_pwm,
uint32_t out_pins[NRF_PWM_CHANNEL_COUNT])
{
uint8_t i;
for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i)
{
p_pwm->PSEL.OUT[i] = out_pins[i];
}
}
__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm,
nrf_pwm_clk_t base_clock,
nrf_pwm_mode_t mode,
uint16_t top_value)
{
ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
p_pwm->PRESCALER = base_clock;
p_pwm->MODE = mode;
p_pwm->COUNTERTOP = top_value;
}
__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_seq)
{
ASSERT(p_seq != NULL);
nrf_pwm_seq_ptr_set( p_pwm, seq_id, p_seq->values.p_raw);
nrf_pwm_seq_cnt_set( p_pwm, seq_id, p_seq->length);
nrf_pwm_seq_refresh_set( p_pwm, seq_id, p_seq->repeats);
nrf_pwm_seq_end_delay_set(p_pwm, seq_id, p_seq->end_delay);
}
__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint16_t const * p_values)
{
ASSERT(seq_id <= 1);
ASSERT(p_values != NULL);
p_pwm->SEQ[seq_id].PTR = (uint32_t)p_values;
}
__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint16_t length)
{
ASSERT(seq_id <= 1);
ASSERT(length != 0);
ASSERT(length <= PWM_SEQ_CNT_CNT_Msk);
p_pwm->SEQ[seq_id].CNT = length;
}
__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint32_t refresh)
{
ASSERT(seq_id <= 1);
ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk);
p_pwm->SEQ[seq_id].REFRESH = refresh;
}
__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm,
uint8_t seq_id,
uint32_t end_delay)
{
ASSERT(seq_id <= 1);
ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk);
p_pwm->SEQ[seq_id].ENDDELAY = end_delay;
}
__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_pwm,
nrf_pwm_dec_load_t dec_load,
nrf_pwm_dec_step_t dec_step)
{
p_pwm->DECODER = ((uint32_t)dec_load << PWM_DECODER_LOAD_Pos) |
((uint32_t)dec_step << PWM_DECODER_MODE_Pos);
}
__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_pwm,
uint16_t loop_count)
{
p_pwm->LOOP = loop_count;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_PWM_H__
/** @} */

View File

@ -0,0 +1,468 @@
/* 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_QDEC_H__
#define NRF_QDEC_H__
#include <stddef.h>
#include "nrf_error.h"
#include "nrf.h"
/*lint ++flb "Enter library region" */
/**
* @defgroup nrf_qdec_hal QDEC HAL
* @{
* @ingroup nrf_qdec
* @brief Hardware access layer for accessing the quadrature decoder (QDEC) peripheral.
*/
/**
* @enum nrf_qdec_task_t
* @brief QDEC tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_QDEC_TASK_START = offsetof(NRF_QDEC_Type, TASKS_START), /**< Starting the quadrature decoder. */
NRF_QDEC_TASK_STOP = offsetof(NRF_QDEC_Type, TASKS_STOP), /**< Stopping the quadrature decoder. */
NRF_QDEC_TASK_READCLRACC = offsetof(NRF_QDEC_Type, TASKS_READCLRACC) /**< Reading and clearing ACC and ACCDBL registers. */
} nrf_qdec_task_t;
/**
* @enum nrf_qdec_event_t
* @brief QDEC events.
*/
typedef enum
{
NRF_QDEC_EVENT_SAMPLERDY = offsetof(NRF_QDEC_Type, EVENTS_SAMPLERDY), /**< Event generated for every new sample. */
NRF_QDEC_EVENT_REPORTRDY = offsetof(NRF_QDEC_Type, EVENTS_REPORTRDY), /**< Event generated for every new report. */
NRF_QDEC_EVENT_ACCOF = offsetof(NRF_QDEC_Type, EVENTS_ACCOF) /**< Event generated for every accumulator overflow. */
} nrf_qdec_event_t; /*lint -restore */
/**
* @enum nrf_qdec_short_mask_t
* @brief QDEC shortcuts.
*/
typedef enum
{
NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK = QDEC_SHORTS_REPORTRDY_READCLRACC_Msk, /**< Shortcut between REPORTRDY event and READCLRACC task. */
NRF_QDEC_SHORT_SAMPLERDY_STOP_MASK = QDEC_SHORTS_SAMPLERDY_STOP_Msk /**< Shortcut between SAMPLERDY event and STOP task. */
} nrf_qdec_short_mask_t;
/**
* @enum nrf_qdec_int_mask_t
* @brief QDEC interrupts.
*/
typedef enum
{
NRF_QDEC_INT_SAMPLERDY_MASK = QDEC_INTENSET_SAMPLERDY_Msk, /**< Mask for enabling or disabling an interrupt on SAMPLERDY event. */
NRF_QDEC_INT_REPORTRDY_MASK = QDEC_INTENSET_REPORTRDY_Msk, /**< Mask for enabling or disabling an interrupt on REPORTRDY event. */
NRF_QDEC_INT_ACCOF_MASK = QDEC_INTENSET_ACCOF_Msk /**< Mask for enabling or disabling an interrupt on ACCOF event. */
} nrf_qdec_int_mask_t;
/**
* @enum nrf_qdec_enable_t
* @brief States of the enable bit.
*/
typedef enum
{
NRF_QDEC_DISABLE = QDEC_ENABLE_ENABLE_Disabled, /**< Mask for disabling the QDEC periperal. When disabled, the QDEC decoder pins are not active. */
NRF_QDEC_ENABLE = QDEC_ENABLE_ENABLE_Enabled /**< Mask for enabling the QDEC periperal. When enabled, the QDEC pins are active. */
} nrf_qdec_enable_t;
/**
* @enum nrf_qdec_dbfen_t
* @brief States of the debounce filter enable bit.
*/
typedef enum
{
NRF_QDEC_DBFEN_DISABLE = QDEC_DBFEN_DBFEN_Disabled, /**< Mask for disabling the debounce filter. */
NRF_QDEC_DBFEN_ENABLE = QDEC_DBFEN_DBFEN_Enabled /**< Mask for enabling the debounce filter. */
} nrf_qdec_dbfen_t;
/**
* @enum nrf_qdec_ledpol_t
* @brief Active LED polarity.
*/
typedef enum
{
NRF_QDEC_LEPOL_ACTIVE_LOW = QDEC_LEDPOL_LEDPOL_ActiveLow, /**< QDEC LED active on output pin low. */
NRF_QDEC_LEPOL_ACTIVE_HIGH = QDEC_LEDPOL_LEDPOL_ActiveHigh /**< QDEC LED active on output pin high. */
} nrf_qdec_ledpol_t;
/**
* @enum nrf_qdec_sampleper_t
* @brief Available sampling periods.
*/
typedef enum
{
NRF_QDEC_SAMPLEPER_128us = QDEC_SAMPLEPER_SAMPLEPER_128us, /**< QDEC sampling period 128 microseconds. */
NRF_QDEC_SAMPLEPER_256us = QDEC_SAMPLEPER_SAMPLEPER_256us, /**< QDEC sampling period 256 microseconds. */
NRF_QDEC_SAMPLEPER_512us = QDEC_SAMPLEPER_SAMPLEPER_512us, /**< QDEC sampling period 512 microseconds. */
NRF_QDEC_SAMPLEPER_1024us = QDEC_SAMPLEPER_SAMPLEPER_1024us, /**< QDEC sampling period 1024 microseconds. */
NRF_QDEC_SAMPLEPER_2048us = QDEC_SAMPLEPER_SAMPLEPER_2048us, /**< QDEC sampling period 2048 microseconds. */
NRF_QDEC_SAMPLEPER_4096us = QDEC_SAMPLEPER_SAMPLEPER_4096us, /**< QDEC sampling period 4096 microseconds. */
NRF_QDEC_SAMPLEPER_8192us = QDEC_SAMPLEPER_SAMPLEPER_8192us, /**< QDEC sampling period 8192 microseconds. */
NRF_QDEC_SAMPLEPER_16384us = QDEC_SAMPLEPER_SAMPLEPER_16384us /**< QDEC sampling period 16384 microseconds. */
} nrf_qdec_sampleper_t;
/**
* @enum nrf_qdec_reportper_t
* @brief Available report periods.
*/
typedef enum
{
NRF_QDEC_REPORTPER_10 = QDEC_REPORTPER_REPORTPER_10Smpl, /**< QDEC report period 10 samples. */
NRF_QDEC_REPORTPER_40 = QDEC_REPORTPER_REPORTPER_40Smpl, /**< QDEC report period 40 samples. */
NRF_QDEC_REPORTPER_80 = QDEC_REPORTPER_REPORTPER_80Smpl, /**< QDEC report period 80 samples. */
NRF_QDEC_REPORTPER_120 = QDEC_REPORTPER_REPORTPER_120Smpl, /**< QDEC report period 120 samples. */
NRF_QDEC_REPORTPER_160 = QDEC_REPORTPER_REPORTPER_160Smpl, /**< QDEC report period 160 samples. */
NRF_QDEC_REPORTPER_200 = QDEC_REPORTPER_REPORTPER_200Smpl, /**< QDEC report period 200 samples. */
NRF_QDEC_REPORTPER_240 = QDEC_REPORTPER_REPORTPER_240Smpl, /**< QDEC report period 240 samples. */
NRF_QDEC_REPORTPER_280 = QDEC_REPORTPER_REPORTPER_280Smpl, /**< QDEC report period 280 samples. */
NRF_QDEC_REPORTPER_DISABLED /**< QDEC reporting disabled. */
} nrf_qdec_reportper_t;
/**
* @brief Function for enabling QDEC.
*/
__STATIC_INLINE void nrf_qdec_enable(void)
{
NRF_QDEC->ENABLE = NRF_QDEC_ENABLE;
}
/**
* @brief Function for disabling QDEC.
*/
__STATIC_INLINE void nrf_qdec_disable(void)
{
NRF_QDEC->ENABLE = NRF_QDEC_DISABLE;
}
/**
* @brief Function for returning the enable state of QDEC.
* @return State of the register.
*/
__STATIC_INLINE uint32_t nrf_qdec_enable_get(void)
{
return NRF_QDEC->ENABLE;
}
/**
* @brief Function for enabling QDEC interrupts by mask.
* @param[in] qdec_int_mask Sources of the interrupts to enable.
*/
__STATIC_INLINE void nrf_qdec_int_enable(uint32_t qdec_int_mask)
{
NRF_QDEC->INTENSET = qdec_int_mask; // writing 0 has no effect
}
/**
* @brief Function for disabling QDEC interrupts by mask.
* @param[in] qdec_int_mask Sources of the interrupts to disable.
*
*/
__STATIC_INLINE void nrf_qdec_int_disable(uint32_t qdec_int_mask)
{
NRF_QDEC->INTENCLR = qdec_int_mask; // writing 0 has no effect
}
/**
* @brief Function for getting the enabled interrupts of the QDEC.
*/
__STATIC_INLINE uint32_t nrf_qdec_int_enable_check(nrf_qdec_int_mask_t qdec_int_mask)
{
return NRF_QDEC->INTENSET & qdec_int_mask; // when read this register will return the value of INTEN.
}
/**
* @brief Function for enabling the debouncing filter of the QED.
*/
__STATIC_INLINE void nrf_qdec_dbfen_enable(void)
{
NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_ENABLE;
}
/**
* @brief Function for disabling the debouncing filter of the QED.
*/
__STATIC_INLINE void nrf_qdec_dbfen_disable(void)
{
NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_DISABLE;
}
/**
* @brief Function for getting the state of the QDEC's debouncing filter.
* @retval NRF_QDEC_DBFEN_DISABLE If the debouncing filter is disabled.
* @retval NRF_QDEC_DBFEN_ENABLE If the debouncing filter is enabled.
*/
__STATIC_INLINE uint32_t nrf_qdec_dbfen_get(void)
{
return NRF_QDEC->DBFEN;
}
/**
* @brief Function for assigning QDEC pins.
* @param[in] psela Pin number.
* @param[in] pselb Pin number.
* @param[in] pselled Pin number.
*/
__STATIC_INLINE void nrf_qdec_pio_assign( uint32_t psela, uint32_t pselb, uint32_t pselled)
{
#ifdef NRF51
NRF_QDEC->PSELA = psela;
NRF_QDEC->PSELB = pselb;
NRF_QDEC->PSELLED = pselled;
#elif defined NRF52
NRF_QDEC->PSEL.A = psela;
NRF_QDEC->PSEL.B = pselb;
NRF_QDEC->PSEL.LED = pselled;
#endif
}
/**
* @brief Function for setting a specific QDEC task.
* @param[in] qdec_task QDEC task to be set.
*/
__STATIC_INLINE void nrf_qdec_task_trigger(nrf_qdec_task_t qdec_task)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task) ) = 1;
}
/**
* @brief Function for retrieving the address of a QDEC task register.
* @param[in] qdec_task QDEC task.
*/
__STATIC_INLINE uint32_t * nrf_qdec_task_address_get(nrf_qdec_task_t qdec_task)
{
return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task);
}
/**
* @brief Function for clearing a specific QDEC event.
* @param[in] qdec_event QDEC event to clear.
*/
__STATIC_INLINE void nrf_qdec_event_clear(nrf_qdec_event_t qdec_event)
{
*( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event) ) = 0;
}
/**
* @brief Function for retrieving the state of a specific QDEC event.
* @return State of the QDEC event.
*/
__STATIC_INLINE uint32_t nrf_qdec_event_check(nrf_qdec_event_t qdec_event)
{
return *(volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event);
}
/**
* @brief Function for retrieving the address of a specific QDEC event register.
* @param[in] qdec_event QDEC event.
* @return Address of the specified QDEC event.
*/
__STATIC_INLINE uint32_t * nrf_qdec_event_address_get(nrf_qdec_event_t qdec_event)
{
return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event);
}
/**
* @brief Function for setting QDEC shortcuts.
* @param[in] qdec_short_mask QDEC shortcut by mask.
*/
__STATIC_INLINE void nrf_qdec_shorts_enable(uint32_t qdec_short_mask)
{
NRF_QDEC->SHORTS |= qdec_short_mask;
}
/**
* @brief Function for clearing shortcuts of the QDEC by mask.
* @param[in] qdec_short_mask QDEC shortcute to be cleared.
*/
__STATIC_INLINE void nrf_qdec_shorts_disable(uint32_t qdec_short_mask)
{
NRF_QDEC->SHORTS &= ~qdec_short_mask;
}
/**
* @brief Function for retrieving the value of QDEC's SAMPLEPER register.
* @return Value of the SAMPLEPER register.
*/
__STATIC_INLINE int32_t nrf_qdec_sampleper_reg_get(void)
{
return NRF_QDEC->SAMPLEPER;
}
/**
* @brief Function for converting the value of QDEC's SAMPLE PERIOD to microseconds.
* @retval sampling period in microseconds.
*/
__STATIC_INLINE uint32_t nrf_qdec_sampleper_to_value(uint32_t sampleper)
{
return (1 << (7+sampleper));
}
/**
* @brief Function for setting the value of QDEC's SAMPLEPER register.
* @param[in] sample_per Sampling period.
*/
__STATIC_INLINE void nrf_qdec_sampleper_set(nrf_qdec_sampleper_t sample_per)
{
NRF_QDEC->SAMPLEPER = sample_per;
}
/**
* @brief Function for retrieving the value of QDEC's SAMPLE register.
* @return Value of the SAMPLE register.
*/
__STATIC_INLINE int32_t nrf_qdec_sample_get(void)
{
return NRF_QDEC->SAMPLE;
}
/**
* @brief Function for retrieving the value of QDEC's ACC register.
* @return Value of the ACC register.
*/
__STATIC_INLINE int32_t nrf_qdec_acc_get(void)
{
return NRF_QDEC->ACC;
}
/**
* @brief Function for retrieving the value of QDEC's ACCREAD register.
* @return Value of the ACCREAD register.
*/
__STATIC_INLINE int32_t nrf_qdec_accread_get(void)
{
return NRF_QDEC->ACCREAD;
}
/**
* @brief Function for retrieving the value of QDEC's ACCDBL register.
* @return Value of the ACCDBL register.
*/
__STATIC_INLINE uint32_t nrf_qdec_accdbl_get(void)
{
return NRF_QDEC->ACCDBL;
}
/**
* @brief Function for retrieving the value of QDEC's ACCDBLREAD register.
* @return Value of the ACCDBLREAD register.
*/
__STATIC_INLINE uint32_t nrf_qdec_accdblread_get(void)
{
return NRF_QDEC->ACCDBLREAD;
}
/**
* @brief Function for setting how long the LED is switched on before sampling.
* @param[in] time_us Time (in microseconds) how long the LED is switched on before sampling.
*/
__STATIC_INLINE void nrf_qdec_ledpre_set(uint32_t time_us)
{
NRF_QDEC->LEDPRE = time_us;
}
/**
* @brief Function for retrieving how long the LED is switched on before sampling.
* @retval time_us Time (in microseconds) how long the LED is switched on before sampling.
*/
__STATIC_INLINE uint32_t nrf_qdec_ledpre_get(void)
{
return NRF_QDEC->LEDPRE;
}
/**
* @brief Function for setting the report period (in samples).
* @param[in] reportper Number of samples.
*/
__STATIC_INLINE void nrf_qdec_reportper_set(nrf_qdec_reportper_t reportper)
{
NRF_QDEC->REPORTPER = reportper;
}
/**
* @brief Function for retrieving the report period.
* @retval reportper Number of samples as encoded in the register.
*/
__STATIC_INLINE uint32_t nrf_qdec_reportper_reg_get(void)
{
return NRF_QDEC->REPORTPER;
}
/**
* @brief Function for retrieving the value of QDEC's SAMPLEPER register.
* @param [in] reportper Reportper to be converted to amount of samples per report.
*/
__STATIC_INLINE uint32_t nrf_qdec_reportper_to_value(uint32_t reportper)
{
return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper*40;
}
/**
* @brief Function for setting the active level for the LED.
* @param[in] pol Active level for the LED.
*/
__STATIC_INLINE void nrf_qdec_ledpol_set(nrf_qdec_ledpol_t pol)
{
NRF_QDEC->LEDPOL = pol;
}
/**
* @brief Function for retrieving the active level for the LED.
* @return Active level for the LED.
*/
__STATIC_INLINE uint32_t nrf_qdec_ledpol_get(void)
{
return NRF_QDEC->LEDPOL;
}
/**
*@}
**/
/*lint --flb "Leave library region" */
#endif

View File

@ -0,0 +1,211 @@
/* 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 RNG HAL API.
*/
#ifndef NRF_RNG_H__
#define NRF_RNG_H__
/**
* @defgroup nrf_rng_hal RNG HAL
* @{
* @ingroup nrf_rng
* @brief Hardware access layer for managing the random number generator (RNG).
*/
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
#define NRF_RNG_TASK_SET (1UL)
#define NRF_RNG_EVENT_CLEAR (0UL)
/**
* @enum nrf_rng_task_t
* @brief RNG tasks.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */
NRF_RNG_TASK_STOP = offsetof(NRF_RNG_Type, TASKS_STOP) /**< Stop the random number generator. */
} nrf_rng_task_t; /*lint -restore */
/**
* @enum nrf_rng_event_t
* @brief RNG events.
*/
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
{
NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */
} nrf_rng_event_t; /*lint -restore */
/**
* @enum nrf_rng_int_mask_t
* @brief RNG interrupts.
*/
typedef enum
{
NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */
} nrf_rng_int_mask_t;
/**
* @enum nrf_rng_short_mask_t
* @brief Types of RNG shortcuts.
*/
typedef enum
{
NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */
} nrf_rng_short_mask_t;
/**
* @brief Function for enabling interrupts.
*
* @param[in] rng_int_mask Mask of interrupts.
*/
__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask)
{
NRF_RNG->INTENSET = rng_int_mask;
}
/**
* @brief Function for disabling interrupts.
*
* @param[in] rng_int_mask Mask of interrupts.
*/
__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask)
{
NRF_RNG->INTENCLR = rng_int_mask;
}
/**
* @brief Function for getting the state of a specific interrupt.
*
* @param[in] rng_int_mask Interrupt.
*
* @retval true If the interrupt is not enabled.
* @retval false If the interrupt is enabled.
*/
__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask)
{
return (bool)(NRF_RNG->INTENCLR & rng_int_mask);
}
/**
* @brief Function for getting the address of a specific task.
*
* This function can be used by the PPI module.
*
* @param[in] rng_task Task.
*/
__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task)
{
return (uint32_t *)((uint8_t *)NRF_RNG + rng_task);
}
/**
* @brief Function for setting a specific task.
*
* @param[in] rng_task Task.
*/
__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET;
}
/**
* @brief Function for getting address of a specific event.
*
* This function can be used by the PPI module.
*
* @param[in] rng_event Event.
*/
__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event)
{
return (uint32_t *)((uint8_t *)NRF_RNG + rng_event);
}
/**
* @brief Function for clearing a specific event.
*
* @param[in] rng_event Event.
*/
__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR;
}
/**
* @brief Function for getting the state of a specific event.
*
* @param[in] rng_event Event.
*
* @retval true If the event is not set.
* @retval false If the event is set.
*/
__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event)
{
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event));
}
/**
* @brief Function for setting shortcuts.
*
* @param[in] rng_short_mask Mask of shortcuts.
*
*/
__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask)
{
NRF_RNG->SHORTS |= rng_short_mask;
}
/**
* @brief Function for clearing shortcuts.
*
* @param[in] rng_short_mask Mask of shortcuts.
*
*/
__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask)
{
NRF_RNG->SHORTS &= ~rng_short_mask;
}
/**
* @brief Function for getting the previously generated random value.
*
* @return Previously generated random value.
*/
__STATIC_INLINE uint8_t nrf_rng_random_value_get(void)
{
return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk);
}
/**
* @brief Function for enabling digital error correction.
*/
__STATIC_INLINE void nrf_rng_error_correction_enable(void)
{
NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk;
}
/**
* @brief Function for disabling digital error correction.
*/
__STATIC_INLINE void nrf_rng_error_correction_disable(void)
{
NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk;
}
/**
*@}
**/
#endif /* NRF_RNG_H__ */

View File

@ -0,0 +1,304 @@
/* 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 RTC HAL API.
*/
#ifndef NRF_RTC_H
#define NRF_RTC_H
/**
* @defgroup nrf_rtc_hal RTC HAL
* @{
* @ingroup nrf_rtc
* @brief Hardware access layer for managing the real time counter (RTC).
*/
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
#include "nrf_assert.h"
/**
* @brief Macro for getting the number of compare channels available
* in a given RTC instance.
*/
#ifdef NRF51
#define NRF_RTC_CC_CHANNEL_COUNT(id) 4
#else
#define NRF_RTC_CC_CHANNEL_COUNT(id) ((id) == 0 ? 3 : 4)
#endif
#define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */
/**< Macro for wrapping values to RTC capacity. */
#define RTC_WRAP(val) (val & RTC_COUNTER_COUNTER_Msk)
#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)NRF_RTC_INT_COMPARE0_MASK << ch)
#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch*sizeof(uint32_t))
/**
* @enum nrf_rtc_task_t
* @brief RTC tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */
NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */
NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */
NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW),/**< Trigger overflow. */
/*lint -restore*/
} nrf_rtc_task_t;
/**
* @enum nrf_rtc_event_t
* @brief RTC events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */
NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */
NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */
NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */
NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */
NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */
/*lint -restore*/
} nrf_rtc_event_t;
/**
* @enum nrf_rtc_int_t
* @brief RTC interrupts.
*/
typedef enum
{
NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */
NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */
NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */
NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */
NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */
NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */
} nrf_rtc_int_t;
/**@brief Function for setting a compare value for a channel.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] ch Channel.
* @param[in] cc_val Compare value to set.
*/
__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val);
/**@brief Function for returning the compare value for a channel.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] ch Channel.
*
* @return COMPARE[ch] value.
*/
__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch);
/**@brief Function for enabling interrupts.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] mask Interrupt mask to be enabled.
*/
__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask);
/**@brief Function for disabling interrupts.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] mask Interrupt mask to be disabled.
*/
__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask);
/**@brief Function for checking if interrupts are enabled.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] mask Mask of interrupt flags to check.
*
* @return Mask with enabled interrupts.
*/
__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask);
/**@brief Function for returning the status of currently enabled interrupts.
*
* @param[in] p_rtc Pointer to the instance register structure.
*
* @return Value in INTEN register.
*/
__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc);
/**@brief Function for checking if an event is pending.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] event Address of the event.
*
* @return Mask of pending events.
*/
__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
/**@brief Function for clearing an event.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
/**@brief Function for returning a counter value.
*
* @param[in] p_rtc Pointer to the instance register structure.
*
* @return Counter value.
*/
__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc);
/**@brief Function for setting a prescaler value.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] val Value to set the prescaler to.
*/
__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val);
/**@brief Function for returning the address of an event.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] event Requested event.
*
* @return Address of the requested event register.
*/
__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event);
/**@brief Function for returning the address of a task.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] task Requested task.
*
* @return Address of the requested task register.
*/
__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task);
/**@brief Function for starting a task.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] task Requested task.
*/
__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task);
/**@brief Function for enabling events.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] mask Mask of event flags to enable.
*/
__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask);
/**@brief Function for disabling an event.
*
* @param[in] p_rtc Pointer to the instance register structure.
* @param[in] event Requested event.
*/
__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event);
/**
*@}
**/
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val)
{
p_rtc->CC[ch] = cc_val;
}
__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch)
{
return p_rtc->CC[ch];
}
__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask)
{
p_rtc->INTENSET = mask;
}
__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask)
{
p_rtc->INTENCLR = mask;
}
__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask)
{
return (p_rtc->INTENSET & mask);
}
__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc)
{
return p_rtc->INTENSET;
}
__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
{
return *(volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event);
}
__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc)
{
return p_rtc->COUNTER;
}
__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val)
{
ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
p_rtc->PRESCALER = val;
}
__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc)
{
return p_rtc->PRESCALER;
}
__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event)
{
return (uint32_t)p_rtc + event;
}
__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task)
{
return (uint32_t)p_rtc + task;
}
__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task)
{
*(__IO uint32_t *)((uint32_t)p_rtc + task) = 1;
}
__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask)
{
p_rtc->EVTENSET = mask;
}
__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t mask)
{
p_rtc->EVTENCLR = mask;
}
#endif
#endif /* NRF_RTC_H */

View File

@ -0,0 +1,31 @@
/* 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.
*
*/
/**
* @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;
}

View File

@ -0,0 +1,554 @@
/* 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_
/**
* @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 /* NRF_SAADC_H_ */

View File

@ -0,0 +1,334 @@
/* 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.
*
*/
/**
* @defgroup nrf_spi_hal SPI HAL
* @{
* @ingroup nrf_spi_master
*
* @brief Hardware access layer for accessing the SPI peripheral.
*/
#ifndef NRF_SPI_H__
#define NRF_SPI_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
/**
* @brief This value can be used as a parameter for the @ref nrf_spi_pins_set
* function to specify that a given SPI signal (SCK, MOSI, or MISO)
* shall not be connected to a physical pin.
*/
#define NRF_SPI_PIN_NOT_CONNECTED 0xFFFFFFFF
/**
* @brief SPI events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_SPI_EVENT_READY = offsetof(NRF_SPI_Type, EVENTS_READY) ///< TXD byte sent and RXD byte received.
/*lint -restore*/
} nrf_spi_event_t;
/**
* @brief SPI interrupts.
*/
typedef enum
{
NRF_SPI_INT_READY_MASK = SPI_INTENSET_READY_Msk ///< Interrupt on READY event.
} nrf_spi_int_mask_t;
/**
* @brief SPI data rates.
*/
typedef enum
{
NRF_SPI_FREQ_125K = SPI_FREQUENCY_FREQUENCY_K125, ///< 125 kbps.
NRF_SPI_FREQ_250K = SPI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
NRF_SPI_FREQ_500K = SPI_FREQUENCY_FREQUENCY_K500, ///< 500 kbps.
NRF_SPI_FREQ_1M = SPI_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps.
NRF_SPI_FREQ_2M = SPI_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps.
NRF_SPI_FREQ_4M = SPI_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps.
// [conversion to 'int' needed to prevent compilers from complaining
// that the provided value (0x80000000UL) is out of range of "int"]
NRF_SPI_FREQ_8M = (int)SPI_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps.
} nrf_spi_frequency_t;
/**
* @brief SPI modes.
*/
typedef enum
{
NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock.
NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock.
NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock.
NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock.
} nrf_spi_mode_t;
/**
* @brief SPI bit orders.
*/
typedef enum
{
NRF_SPI_BIT_ORDER_MSB_FIRST = SPI_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
NRF_SPI_BIT_ORDER_LSB_FIRST = SPI_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
} nrf_spi_bit_order_t;
/**
* @brief Function for clearing a specific SPI event.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_event Event to clear.
*/
__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event);
/**
* @brief Function for checking the state of a specific SPI event.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_event Event to check.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event);
/**
* @brief Function for getting the address of a specific SPI event register.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi,
uint32_t spi_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi,
uint32_t spi_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi,
nrf_spi_int_mask_t spi_int);
/**
* @brief Function for enabling the SPI peripheral.
*
* @param[in] p_spi SPI instance.
*/
__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi);
/**
* @brief Function for disabling the SPI peripheral.
*
* @param[in] p_spi SPI instance.
*/
__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi);
/**
* @brief Function for configuring SPI pins.
*
* If a given signal is not needed, pass the @ref NRF_SPI_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_spi SPI instance.
* @param[in] sck_pin SCK pin number.
* @param[in] mosi_pin MOSI pin number.
* @param[in] miso_pin MISO pin number.
*/
__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin);
/**
* @brief Function for writing data to the SPI transmitter register.
*
* @param[in] p_spi SPI instance.
* @param[in] data TX data to send.
*/
__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data);
/**
* @brief Function for reading data from the SPI receiver register.
*
* @param[in] p_spi SPI instance.
*
* @return RX data received.
*/
__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi);
/**
* @brief Function for setting the SPI master data rate.
*
* @param[in] p_spi SPI instance.
* @param[in] frequency SPI frequency.
*/
__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi,
nrf_spi_frequency_t frequency);
/**
* @brief Function for setting the SPI configuration.
*
* @param[in] p_spi SPI instance.
* @param[in] spi_mode SPI mode.
* @param[in] spi_bit_order SPI bit order.
*/
__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi,
nrf_spi_mode_t spi_mode,
nrf_spi_bit_order_t spi_bit_order);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event)
{
*((volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event);
}
__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi,
nrf_spi_event_t spi_event)
{
return (uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event);
}
__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi,
uint32_t spi_int_mask)
{
p_spi->INTENSET = spi_int_mask;
}
__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi,
uint32_t spi_int_mask)
{
p_spi->INTENCLR = spi_int_mask;
}
__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi,
nrf_spi_int_mask_t spi_int)
{
return (bool)(p_spi->INTENSET & spi_int);
}
__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi)
{
p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi)
{
p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin)
{
p_spi->PSELSCK = sck_pin;
p_spi->PSELMOSI = mosi_pin;
p_spi->PSELMISO = miso_pin;
}
__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data)
{
p_spi->TXD = data;
}
__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi)
{
return p_spi->RXD;
}
__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi,
nrf_spi_frequency_t frequency)
{
p_spi->FREQUENCY = frequency;
}
__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi,
nrf_spi_mode_t spi_mode,
nrf_spi_bit_order_t spi_bit_order)
{
uint32_t config = (spi_bit_order == NRF_SPI_BIT_ORDER_MSB_FIRST ?
SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst);
switch (spi_mode)
{
default:
case NRF_SPI_MODE_0:
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) |
(SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
break;
case NRF_SPI_MODE_1:
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) |
(SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
break;
case NRF_SPI_MODE_2:
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) |
(SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
break;
case NRF_SPI_MODE_3:
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) |
(SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
break;
}
p_spi->CONFIG = config;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_SPI_H__
/** @} */

View File

@ -0,0 +1,520 @@
/* 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.
*
*/
/**
* @defgroup nrf_spim_hal SPIM HAL
* @{
* @ingroup nrf_spi_master
*
* @brief Hardware access layer for accessing the SPIM peripheral.
*/
#ifndef NRF_SPIM_H__
#define NRF_SPIM_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
/**
* @brief This value can be used as a parameter for the @ref nrf_spim_pins_set
* function to specify that a given SPI signal (SCK, MOSI, or MISO)
* shall not be connected to a physical pin.
*/
#define NRF_SPIM_PIN_NOT_CONNECTED 0xFFFFFFFF
/**
* @brief SPIM tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_SPIM_TASK_START = offsetof(NRF_SPIM_Type, TASKS_START), ///< Start SPI transaction.
NRF_SPIM_TASK_STOP = offsetof(NRF_SPIM_Type, TASKS_STOP), ///< Stop SPI transaction.
NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction.
NRF_SPIM_TASK_RESUME = offsetof(NRF_SPIM_Type, TASKS_RESUME) ///< Resume SPI transaction.
/*lint -restore*/
} nrf_spim_task_t;
/**
* @brief SPIM events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped.
NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached.
#ifdef NRF52
NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached.
#endif
NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached.
NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started.
/*lint -restore*/
} nrf_spim_event_t;
#ifdef NRF52
/**
* @brief SPIM shortcuts.
*/
typedef enum
{
NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task.
} nrf_spim_short_mask_t;
#endif
/**
* @brief SPIM interrupts.
*/
typedef enum
{
NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
#ifdef NRF52
NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event.
#endif
NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event.
NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event.
} nrf_spim_int_mask_t;
/**
* @brief SPI master data rates.
*/
typedef enum
{
NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125, ///< 125 kbps.
NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500, ///< 500 kbps.
NRF_SPIM_FREQ_1M = SPIM_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps.
NRF_SPIM_FREQ_2M = SPIM_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps.
NRF_SPIM_FREQ_4M = SPIM_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps.
// [conversion to 'int' needed to prevent compilers from complaining
// that the provided value (0x80000000UL) is out of range of "int"]
NRF_SPIM_FREQ_8M = (int)SPIM_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps.
} nrf_spim_frequency_t;
/**
* @brief SPI modes.
*/
typedef enum
{
NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock.
NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock.
NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock.
NRF_SPIM_MODE_3 ///< SCK active low, sample on trailing edge of clock.
} nrf_spim_mode_t;
/**
* @brief SPI bit orders.
*/
typedef enum
{
NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
} nrf_spim_bit_order_t;
/**
* @brief Function for activating a specific SPIM task.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_task Task to activate.
*/
__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim,
nrf_spim_task_t spim_task);
/**
* @brief Function for getting the address of a specific SPIM task register.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim,
nrf_spim_task_t spim_task);
/**
* @brief Function for clearing a specific SPIM event.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_event Event to clear.
*/
__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event);
/**
* @brief Function for checking the state of a specific SPIM event.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_event Event to check.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event);
/**
* @brief Function for getting the address of a specific SPIM event register.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event);
#ifdef NRF52
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim,
uint32_t spim_shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim,
uint32_t spim_shorts_mask);
/**
* @brief Function for getting shorts setting.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim);
#endif
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim,
uint32_t spim_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim,
uint32_t spim_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_spim SPIM instance.
* @param[in] spim_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim,
nrf_spim_int_mask_t spim_int);
/**
* @brief Function for enabling the SPIM peripheral.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim);
/**
* @brief Function for disabling the SPIM peripheral.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim);
/**
* @brief Function for configuring SPIM pins.
*
* If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_spim SPIM instance.
* @param[in] sck_pin SCK pin number.
* @param[in] mosi_pin MOSI pin number.
* @param[in] miso_pin MISO pin number.
*/
__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin);
/**
* @brief Function for setting the SPI master data rate.
*
* @param[in] p_spim SPIM instance.
* @param[in] frequency SPI frequency.
*/
__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim,
nrf_spim_frequency_t frequency);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_spim SPIM instance.
* @param[in] p_buffer Pointer to the buffer with data to send.
* @param[in] length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim,
uint8_t const * p_buffer,
uint8_t length);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_spim SPIM instance.
* @param[in] p_buffer Pointer to the buffer for received data.
* @param[in] length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim,
uint8_t * p_buffer,
uint8_t length);
/**
* @brief Function for setting the SPI configuration.
*
* @param[in] p_spim SPIM instance.
* @param[in] spi_mode SPI mode.
* @param[in] spi_bit_order SPI bit order.
*/
__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim,
nrf_spim_mode_t spi_mode,
nrf_spim_bit_order_t spi_bit_order);
/**
* @brief Function for setting the over-read character.
*
* @param[in] p_spim SPIM instance.
* @param[in] orc Over-read character that is clocked out in case of
* an over-read of the TXD buffer.
*/
__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim,
uint8_t orc);
#ifdef NRF52
/**
* @brief Function for enabling the TX list feature.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim);
/**
* @brief Function for disabling the TX list feature.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim);
/**
* @brief Function for enabling the RX list feature.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim);
/**
* @brief Function for disabling the RX list feature.
*
* @param[in] p_spim SPIM instance.
*/
__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim);
#endif
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim,
nrf_spim_task_t spim_task)
{
*((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim,
nrf_spim_task_t spim_task)
{
return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_task);
}
__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event)
{
*((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event);
}
__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim,
nrf_spim_event_t spim_event)
{
return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_event);
}
#ifdef NRF52
__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim,
uint32_t spim_shorts_mask)
{
p_spim->SHORTS |= spim_shorts_mask;
}
__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim,
uint32_t spim_shorts_mask)
{
p_spim->SHORTS &= ~(spim_shorts_mask);
}
__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim)
{
return p_spim->SHORTS;
}
#endif
__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim,
uint32_t spim_int_mask)
{
p_spim->INTENSET = spim_int_mask;
}
__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim,
uint32_t spim_int_mask)
{
p_spim->INTENCLR = spim_int_mask;
}
__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim,
nrf_spim_int_mask_t spim_int)
{
return (bool)(p_spim->INTENSET & spim_int);
}
__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim)
{
p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim)
{
p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin)
{
p_spim->PSEL.SCK = sck_pin;
p_spim->PSEL.MOSI = mosi_pin;
p_spim->PSEL.MISO = miso_pin;
}
__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim,
nrf_spim_frequency_t frequency)
{
p_spim->FREQUENCY = frequency;
}
__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim,
uint8_t const * p_buffer,
uint8_t length)
{
p_spim->TXD.PTR = (uint32_t)p_buffer;
p_spim->TXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim,
uint8_t * p_buffer,
uint8_t length)
{
p_spim->RXD.PTR = (uint32_t)p_buffer;
p_spim->RXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim,
nrf_spim_mode_t spi_mode,
nrf_spim_bit_order_t spi_bit_order)
{
uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ?
SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst);
switch (spi_mode)
{
default:
case NRF_SPIM_MODE_0:
config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
break;
case NRF_SPIM_MODE_1:
config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
break;
case NRF_SPIM_MODE_2:
config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
break;
case NRF_SPIM_MODE_3:
config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
break;
}
p_spim->CONFIG = config;
}
__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim,
uint8_t orc)
{
p_spim->ORC = orc;
}
#ifdef NRF52
__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim)
{
p_spim->TXD.LIST = 1;
}
__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim)
{
p_spim->TXD.LIST = 0;
}
__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim)
{
p_spim->RXD.LIST = 1;
}
__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim)
{
p_spim->RXD.LIST = 0;
}
#endif
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_SPIM_H__
/** @} */

View File

@ -0,0 +1,512 @@
/* 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.
*
*/
/**
* @defgroup nrf_spis_hal SPIS HAL
* @{
* @ingroup nrf_spis
*
* @brief Hardware access layer for accessing the SPIS peripheral.
*/
#ifndef NRF_SPIS_H__
#define NRF_SPIS_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
/**
* @brief This value can be used as a parameter for the @ref nrf_spis_pins_set
* function to specify that a given SPI signal (SCK, MOSI, or MISO)
* shall not be connected to a physical pin.
*/
#define NRF_SPIS_PIN_NOT_CONNECTED 0xFFFFFFFF
/**
* @brief SPIS tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_SPIS_TASK_ACQUIRE = offsetof(NRF_SPIS_Type, TASKS_ACQUIRE), ///< Acquire SPI semaphore.
NRF_SPIS_TASK_RELEASE = offsetof(NRF_SPIS_Type, TASKS_RELEASE), ///< Release SPI semaphore, enabling the SPI slave to acquire it.
/*lint -restore*/
} nrf_spis_task_t;
/**
* @brief SPIS events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_SPIS_EVENT_END = offsetof(NRF_SPIS_Type, EVENTS_END), ///< Granted transaction completed.
NRF_SPIS_EVENT_ACQUIRED = offsetof(NRF_SPIS_Type, EVENTS_ACQUIRED) ///< Semaphore acquired.
/*lint -restore*/
} nrf_spis_event_t;
/**
* @brief SPIS shortcuts.
*/
typedef enum
{
NRF_SPIS_SHORT_END_ACQUIRE = SPIS_SHORTS_END_ACQUIRE_Msk ///< Shortcut between END event and ACQUIRE task.
} nrf_spis_short_mask_t;
/**
* @brief SPIS interrupts.
*/
typedef enum
{
NRF_SPIS_INT_END_MASK = SPIS_INTENSET_END_Msk, ///< Interrupt on END event.
NRF_SPIS_INT_ACQUIRED_MASK = SPIS_INTENSET_ACQUIRED_Msk ///< Interrupt on ACQUIRED event.
} nrf_spis_int_mask_t;
/**
* @brief SPI modes.
*/
typedef enum
{
NRF_SPIS_MODE_0, ///< SCK active high, sample on leading edge of clock.
NRF_SPIS_MODE_1, ///< SCK active high, sample on trailing edge of clock.
NRF_SPIS_MODE_2, ///< SCK active low, sample on leading edge of clock.
NRF_SPIS_MODE_3 ///< SCK active low, sample on trailing edge of clock.
} nrf_spis_mode_t;
/**
* @brief SPI bit orders.
*/
typedef enum
{
NRF_SPIS_BIT_ORDER_MSB_FIRST = SPIS_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
NRF_SPIS_BIT_ORDER_LSB_FIRST = SPIS_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
} nrf_spis_bit_order_t;
/**
* @brief SPI semaphore status.
*/
typedef enum
{
NRF_SPIS_SEMSTAT_FREE = 0, ///< Semaphore is free.
NRF_SPIS_SEMSTAT_CPU = 1, ///< Semaphore is assigned to the CPU.
NRF_SPIS_SEMSTAT_SPIS = 2, ///< Semaphore is assigned to the SPI slave.
NRF_SPIS_SEMSTAT_CPUPENDING = 3 ///< Semaphore is assigned to the SPI, but a handover to the CPU is pending.
} nrf_spis_semstat_t;
/**
* @brief SPIS status.
*/
typedef enum
{
NRF_SPIS_STATUS_OVERREAD = SPIS_STATUS_OVERREAD_Msk, ///< TX buffer over-read detected and prevented.
NRF_SPIS_STATUS_OVERFLOW = SPIS_STATUS_OVERFLOW_Msk ///< RX buffer overflow detected and prevented.
} nrf_spis_status_mask_t;
/**
* @brief Function for activating a specific SPIS task.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_task Task to activate.
*/
__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis,
nrf_spis_task_t spis_task);
/**
* @brief Function for getting the address of a specific SPIS task register.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis,
nrf_spis_task_t spis_task);
/**
* @brief Function for clearing a specific SPIS event.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_event Event to clear.
*/
__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis,
nrf_spis_event_t spis_event);
/**
* @brief Function for checking the state of a specific SPIS event.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_event Event to check.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis,
nrf_spis_event_t spis_event);
/**
* @brief Function for getting the address of a specific SPIS event register.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis,
nrf_spis_event_t spis_event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis,
uint32_t spis_shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis,
uint32_t spis_shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis,
uint32_t spis_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis,
uint32_t spis_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_spis SPIS instance.
* @param[in] spis_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis,
nrf_spis_int_mask_t spis_int);
/**
* @brief Function for enabling the SPIS peripheral.
*
* @param[in] p_spis SPIS instance.
*/
__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis);
/**
* @brief Function for disabling the SPIS peripheral.
*
* @param[in] p_spis SPIS instance.
*/
__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis);
/**
* @brief Function for retrieving the SPIS semaphore status.
*
* @param[in] p_spis SPIS instance.
*
* @returns Current semaphore status.
*/
__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis);
/**
* @brief Function for retrieving the SPIS status.
*
* @param[in] p_spis SPIS instance.
*
* @returns Current SPIS status.
*/
__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis);
/**
* @brief Function for configuring SPIS pins.
*
* If a given signal is not needed, pass the @ref NRF_SPIS_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_spis SPIS instance.
* @param[in] sck_pin SCK pin number.
* @param[in] mosi_pin MOSI pin number.
* @param[in] miso_pin MISO pin number.
* @param[in] csn_pin CSN pin number.
*/
__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin,
uint32_t csn_pin);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_spis SPIS instance.
* @param[in] p_buffer Pointer to the buffer that contains the data to send.
* @param[in] length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis,
uint8_t const * p_buffer,
uint8_t length);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_spis SPIS instance.
* @param[in] p_buffer Pointer to the buffer for received data.
* @param[in] length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis,
uint8_t * p_buffer,
uint8_t length);
/**
* @brief Function for getting the number of bytes transmitted
* in the last granted transaction.
*
* @param[in] p_spis SPIS instance.
*
* @returns Number of bytes transmitted.
*/
__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis);
/**
* @brief Function for getting the number of bytes received
* in the last granted transaction.
*
* @param[in] p_spis SPIS instance.
*
* @returns Number of bytes received.
*/
__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis);
/**
* @brief Function for setting the SPI configuration.
*
* @param[in] p_spis SPIS instance.
* @param[in] spi_mode SPI mode.
* @param[in] spi_bit_order SPI bit order.
*/
__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis,
nrf_spis_mode_t spi_mode,
nrf_spis_bit_order_t spi_bit_order);
/**
* @brief Function for setting the default character.
*
* @param[in] p_spis SPIS instance.
* @param[in] def Default character that is clocked out in case of
* an overflow of the RXD buffer.
*/
__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis,
uint8_t def);
/**
* @brief Function for setting the over-read character.
*
* @param[in] p_spis SPIS instance.
* @param[in] orc Over-read character that is clocked out in case of
* an over-read of the TXD buffer.
*/
__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis,
uint8_t orc);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis,
nrf_spis_task_t spis_task)
{
*((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis,
nrf_spis_task_t spis_task)
{
return (uint32_t)p_spis + (uint32_t)spis_task;
}
__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis,
nrf_spis_event_t spis_event)
{
*((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis,
nrf_spis_event_t spis_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event);
}
__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis,
nrf_spis_event_t spis_event)
{
return (uint32_t)p_spis + (uint32_t)spis_event;
}
__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis,
uint32_t spis_shorts_mask)
{
p_spis->SHORTS |= spis_shorts_mask;
}
__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis,
uint32_t spis_shorts_mask)
{
p_spis->SHORTS &= ~(spis_shorts_mask);
}
__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis,
uint32_t spis_int_mask)
{
p_spis->INTENSET = spis_int_mask;
}
__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis,
uint32_t spis_int_mask)
{
p_spis->INTENCLR = spis_int_mask;
}
__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis,
nrf_spis_int_mask_t spis_int)
{
return (bool)(p_spis->INTENSET & spis_int);
}
__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis)
{
p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis)
{
p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis)
{
return (nrf_spis_semstat_t) ((p_spis->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk)
>> SPIS_SEMSTAT_SEMSTAT_Pos);
}
__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis)
{
return (nrf_spis_status_mask_t) p_spis->STATUS;
}
__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin,
uint32_t csn_pin)
{
p_spis->PSELSCK = sck_pin;
p_spis->PSELMOSI = mosi_pin;
p_spis->PSELMISO = miso_pin;
p_spis->PSELCSN = csn_pin;
}
__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis,
uint8_t const * p_buffer,
uint8_t length)
{
p_spis->TXDPTR = (uint32_t)p_buffer;
p_spis->MAXTX = length;
}
__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis,
uint8_t * p_buffer,
uint8_t length)
{
p_spis->RXDPTR = (uint32_t)p_buffer;
p_spis->MAXRX = length;
}
__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis)
{
return (uint8_t) p_spis->AMOUNTRX;
}
__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis)
{
return (uint8_t) p_spis->AMOUNTTX;
}
__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis,
nrf_spis_mode_t spi_mode,
nrf_spis_bit_order_t spi_bit_order)
{
uint32_t config = (spi_bit_order == NRF_SPIS_BIT_ORDER_MSB_FIRST ?
SPIS_CONFIG_ORDER_MsbFirst : SPIS_CONFIG_ORDER_LsbFirst);
switch (spi_mode)
{
default:
case NRF_SPIS_MODE_0:
config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) |
(SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos);
break;
case NRF_SPIS_MODE_1:
config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) |
(SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos);
break;
case NRF_SPIS_MODE_2:
config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) |
(SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos);
break;
case NRF_SPIS_MODE_3:
config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) |
(SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos);
break;
}
p_spis->CONFIG = config;
}
__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis,
uint8_t orc)
{
p_spis->ORC = orc;
}
__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis,
uint8_t def)
{
p_spis->DEF = def;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_SPIS_H__
/** @} */

View File

@ -0,0 +1,55 @@
/* Copyright (c) 2012 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_TEMP_H__
#define NRF_TEMP_H__
#include "nrf.h"
/**
* @defgroup nrf_temperature TEMP (temperature) abstraction
* @{
* @ingroup nrf_drivers temperature_example
* @brief Temperature module init and read functions.
*
*/
/**@cond NO_DOXYGEN */
#define MASK_SIGN (0x00000200UL)
#define MASK_SIGN_EXTENSION (0xFFFFFC00UL)
/**
* @brief Function for preparing the temp module for temperature measurement.
*
* This function initializes the TEMP module and writes to the hidden configuration register.
*/
static __INLINE void nrf_temp_init(void)
{
/**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */
*(uint32_t *) 0x4000C504 = 0;
}
/**
* @brief Function for reading temperature measurement.
*
* The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value.
*/
static __INLINE int32_t nrf_temp_read(void)
{
/**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */
return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP);
}
/**@endcond */
/** @} */
#endif

View File

@ -0,0 +1,576 @@
/* 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.
*
*/
/**
* @defgroup nrf_timer_hal Timer HAL
* @{
* @ingroup nrf_timer
*
* @brief Hardware access layer for accessing the timer peripheral.
*/
#ifndef NRF_TIMER_H__
#define NRF_TIMER_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_assert.h"
/**
* @brief Macro for validating the correctness of the BIT_WIDTH setting.
*/
#ifdef NRF51
/**
* In the nRF51 Series, timer instance 0 supports all available bit widths.
* The other two instances support only 8 and 16 bits.
*/
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_timer, bit_width) \
((p_timer == NRF_TIMER0) || (bit_width <= NRF_TIMER_BIT_WIDTH_16))
#else
/**
* In the nRF52 Series, all timer instances support all available bit widths.
*/
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_timer, bit_width) true
#endif
/**
* @brief Macro for getting the number of capture/compare channels available
* in a given timer instance.
*/
#ifdef NRF51
#define NRF_TIMER_CC_CHANNEL_COUNT(id) 4
#else
#define NRF_TIMER_CC_CHANNEL_COUNT(id) ((id) <= 2 ? 4 : 6)
#endif
/**
* @brief Timer tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer.
NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer.
NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode).
NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value.
NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer.
NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0.
NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1.
NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2.
NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3.
#ifdef NRF52
NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4.
NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5.
#endif
/*lint -restore*/
} nrf_timer_task_t;
/**
* @brief Timer events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0.
NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1.
NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2.
NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3.
#ifdef NRF52
NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4.
NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5.
#endif
/*lint -restore*/
} nrf_timer_event_t;
/**
* @brief Types of timer shortcuts.
*/
typedef enum
{
NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0.
NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1.
NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2.
NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3.
#ifdef NRF52
NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4.
NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5.
#endif
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0.
NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1.
NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2.
NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3.
#ifdef NRF52
NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4.
NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5.
#endif
} nrf_timer_short_mask_t;
/**
* @brief Timer modes.
*/
typedef enum
{
NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer.
NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter.
#ifdef NRF52
NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter.
#endif
} nrf_timer_mode_t;
/**
* @brief Timer bit width.
*/
typedef enum
{
NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit.
NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit.
NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit.
NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit.
} nrf_timer_bit_width_t;
/**
* @brief Timer prescalers.
*/
typedef enum
{
NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz.
NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz.
NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz.
NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz.
NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz.
NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz.
NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz.
NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz.
NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz.
NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz.
} nrf_timer_frequency_t;
/**
* @brief Timer capture/compare channels.
*/
typedef enum
{
NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0.
NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1.
NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2.
NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3.
#ifdef NRF52
NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4.
NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5.
#endif
} nrf_timer_cc_channel_t;
/**
* @brief Timer interrupts.
*/
typedef enum
{
NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0.
NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1.
NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2.
NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3.
#ifdef NRF52
NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4.
NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5.
#endif
} nrf_timer_int_mask_t;
/**
* @brief Function for activating a specific timer task.
*
* @param[in] p_timer Timer instance.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_timer,
nrf_timer_task_t task);
/**
* @brief Function for getting the address of a specific timer task register.
*
* @param[in] p_timer Timer instance.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_timer,
nrf_timer_task_t task);
/**
* @brief Function for clearing a specific timer event.
*
* @param[in] p_timer Timer instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event);
/**
* @brief Function for checking the state of a specific timer event.
*
* @param[in] p_timer Timer instance.
* @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_timer_event_check(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event);
/**
* @brief Function for getting the address of a specific timer event register.
*
* @param[in] p_timer Timer instance.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_timer Timer instance.
* @param[in] timer_shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_timer,
uint32_t timer_shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_timer Timer instance.
* @param[in] timer_shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_timer,
uint32_t timer_shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_timer Timer instance.
* @param[in] timer_int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_timer,
uint32_t timer_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_timer Timer instance.
* @param[in] timer_int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_timer,
uint32_t timer_int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_timer Timer instance.
* @param[in] timer_int Interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_timer,
uint32_t timer_int);
/**
* @brief Function for setting the timer mode.
*
* @param[in] p_timer Timer instance.
* @param[in] mode Timer mode.
*/
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_timer,
nrf_timer_mode_t mode);
/**
* @brief Function for retrieving the timer mode.
*
* @param[in] p_timer Timer instance.
*
* @return Timer mode.
*/
__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_timer);
/**
* @brief Function for setting the timer bit width.
*
* @param[in] p_timer Timer instance.
* @param[in] bit_width Timer bit width.
*/
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_timer,
nrf_timer_bit_width_t bit_width);
/**
* @brief Function for retrieving the timer bit width.
*
* @param[in] p_timer Timer instance.
*
* @return Timer bit width.
*/
__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_timer);
/**
* @brief Function for setting the timer frequency.
*
* @param[in] p_timer Timer instance.
* @param[in] frequency Timer frequency.
*/
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_timer,
nrf_timer_frequency_t frequency);
/**
* @brief Function for retrieving the timer frequency.
*
* @param[in] p_timer Timer instance.
*
* @return Timer frequency.
*/
__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_timer);
/**
* @brief Function for writing the capture/compare register for a specified channel.
*
* @param[in] p_timer Timer instance.
* @param[in] cc_channel Requested capture/compare channel.
* @param[in] cc_value Value to write to the capture/compare register.
*/
__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_timer,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value);
/**
* @brief Function for retrieving the capture/compare value for a specified channel.
*
* @param[in] p_timer Timer instance.
* @param[in] cc_channel Requested capture/compare channel.
*
* @return Value from the requested capture/compare register.
*/
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_timer,
nrf_timer_cc_channel_t cc_channel);
/**
* @brief Function for getting a specific timer capture task.
*
* @param[in] channel Capture channel.
*
* @return Capture task.
*/
__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel);
/**
* @brief Function for getting a specific timer compare event.
*
* @param[in] channel Compare channel.
*
* @return Compare event.
*/
__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel);
/**
* @brief Function for getting a specific timer compare interrupt.
*
* @param[in] channel Compare channel.
*
* @return Compare interrupt.
*/
__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel);
/**
* @brief Function for calculating the number of timer ticks for a given time
* (in microseconds) and timer frequency.
*
* @param[in] time_us Time in microseconds.
* @param[in] frequency Timer frequency.
*
* @return Number of timer ticks.
*/
__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
nrf_timer_frequency_t frequency);
/**
* @brief Function for calculating the number of timer ticks for a given time
* (in milliseconds) and timer frequency.
*
* @param[in] time_ms Time in milliseconds.
* @param[in] frequency Timer frequency.
*
* @return Number of timer ticks.
*/
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_timer,
nrf_timer_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_timer,
nrf_timer_task_t task)
{
return (uint32_t *)((uint8_t *)p_timer + (uint32_t)task);
}
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_timer,
nrf_timer_event_t event)
{
return (uint32_t *)((uint8_t *)p_timer + (uint32_t)event);
}
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_timer,
uint32_t timer_shorts_mask)
{
p_timer->SHORTS |= timer_shorts_mask;
}
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_timer,
uint32_t timer_shorts_mask)
{
p_timer->SHORTS &= ~(timer_shorts_mask);
}
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_timer,
uint32_t timer_int_mask)
{
p_timer->INTENSET = timer_int_mask;
}
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_timer,
uint32_t timer_int_mask)
{
p_timer->INTENCLR = timer_int_mask;
}
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_timer,
uint32_t timer_int)
{
return (bool)(p_timer->INTENSET & timer_int);
}
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_timer,
nrf_timer_mode_t mode)
{
p_timer->MODE = (p_timer->MODE & ~TIMER_MODE_MODE_Msk) |
((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk);
}
__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_timer)
{
return (nrf_timer_mode_t)(p_timer->MODE);
}
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_timer,
nrf_timer_bit_width_t bit_width)
{
p_timer->BITMODE = (p_timer->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) |
((bit_width << TIMER_BITMODE_BITMODE_Pos) &
TIMER_BITMODE_BITMODE_Msk);
}
__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_timer)
{
return (nrf_timer_bit_width_t)(p_timer->BITMODE);
}
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_timer,
nrf_timer_frequency_t frequency)
{
p_timer->PRESCALER = (p_timer->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) |
((frequency << TIMER_PRESCALER_PRESCALER_Pos) &
TIMER_PRESCALER_PRESCALER_Msk);
}
__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_timer)
{
return (nrf_timer_frequency_t)(p_timer->PRESCALER);
}
__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_timer,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value)
{
p_timer->CC[cc_channel] = cc_value;
}
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_timer,
nrf_timer_cc_channel_t cc_channel)
{
return (uint32_t)p_timer->CC[cc_channel];
}
__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel)
{
return (nrf_timer_task_t)
((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel)
{
return (nrf_timer_event_t)
((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel)
{
return (nrf_timer_int_mask_t)
((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel);
}
__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16 MHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
ASSERT(time_us <= (UINT32_MAX / 16UL));
return ((time_us * 16UL) >> prescaler);
}
__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms,
nrf_timer_frequency_t frequency)
{
// The "frequency" parameter here is actually the prescaler value, and the
// timer runs at the following frequency: f = 16000 kHz / 2^prescaler.
uint32_t prescaler = (uint32_t)frequency;
ASSERT(time_ms <= (UINT32_MAX / 16000UL));
return ((time_ms * 16000UL) >> prescaler);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_TIMER_H__
/** @} */

View File

@ -0,0 +1,402 @@
/* 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_TWI_H__
#define NRF_TWI_H__
/**
* @defgroup nrf_twi_hal TWI HAL
* @{
* @ingroup nrf_twi_master
*
* @brief Hardware access layer for managing the TWI peripheral.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
/**
* @brief TWI tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence.
NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence.
NRF_TWI_TASK_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), ///< Stop TWI transaction.
NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction.
NRF_TWI_TASK_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) ///< Resume TWI transaction.
/*lint -restore*/
} nrf_twi_task_t;
/**
* @brief TWI events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TWI_EVENT_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), ///< TWI stopped.
NRF_TWI_EVENT_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received.
NRF_TWI_EVENT_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), ///< TWI TXD byte sent.
NRF_TWI_EVENT_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), ///< TWI error.
NRF_TWI_EVENT_BB = offsetof(NRF_TWI_Type, EVENTS_BB), ///< TWI byte boundary, generated before each byte that is sent or received.
NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state.
/*lint -restore*/
} nrf_twi_event_t;
/**
* @brief TWI shortcuts.
*/
typedef enum
{
NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, ///< Shortcut between BB event and SUSPEND task.
NRF_TWI_SHORT_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, ///< Shortcut between BB event and STOP task.
} nrf_twi_short_mask_t;
/**
* @brief TWI interrupts.
*/
typedef enum
{
NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, ///< Interrupt on RXDREADY event.
NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, ///< Interrupt on TXDSENT event.
NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, ///< Interrupt on BB event.
NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk ///< Interrupt on SUSPENDED event.
} nrf_twi_int_mask_t;
/**
* @brief TWI error source.
*/
typedef enum
{
NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address.
NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte.
NRF_TWI_ERROR_OVERRUN = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error.
/**< A new byte was received before the previous byte was read
* from the RXD register (previous data is lost). */
} nrf_twi_error_t;
/**
* @brief TWI master clock frequency.
*/
typedef enum
{
NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps.
NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps.
} nrf_twi_frequency_t;
/**
* @brief Function for activating a specific TWI task.
*
* @param[in] p_twi TWI instance.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_twi,
nrf_twi_task_t task);
/**
* @brief Function for getting the address of a specific TWI task register.
*
* @param[in] p_twi TWI instance.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi,
nrf_twi_task_t task);
/**
* @brief Function for clearing a specific TWI event.
*
* @param[in] p_twi TWI instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi,
nrf_twi_event_t event);
/**
* @brief Function for checking the state of a specific event.
*
* @param[in] p_twi TWI instance.
* @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_twi_event_check(NRF_TWI_Type * p_twi,
nrf_twi_event_t event);
/**
* @brief Function for getting the address of a specific TWI event register.
*
* @param[in] p_twi TWI instance.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi,
nrf_twi_event_t event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_twi TWI instance.
* @param[in] shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_twi,
uint32_t shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_twi TWI instance.
* @param[in] shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_twi,
uint32_t shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_twi TWI instance.
* @param[in] int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi,
uint32_t int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_twi TWI instance.
* @param[in] int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi,
uint32_t int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_twi TWI instance.
* @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_twi_int_enable_check(NRF_TWI_Type * p_twi,
nrf_twi_int_mask_t int_mask);
/**
* @brief Function for enabling the TWI peripheral.
*
* @param[in] p_twi TWI instance.
*/
__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi);
/**
* @brief Function for disabling the TWI peripheral.
*
* @param[in] p_twi TWI instance.
*/
__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi);
/**
* @brief Function for configuring TWI pins.
*
*
* @param[in] p_twi TWI instance.
* @param[in] scl_pin SCL pin number.
* @param[in] sda_pin SDA pin number.
*/
__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi,
uint32_t scl_pin,
uint32_t sda_pin);
/**
* @brief Function for setting the TWI master clock frequency.
*
* @param[in] p_twi TWI instance.
* @param[in] frequency TWI frequency.
*/
__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi,
nrf_twi_frequency_t frequency);
/**
* @brief Function for checking the TWI error source.
*
* The error flags are cleared after reading.
*
* @param[in] p_twi TWI instance.
*
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_twi);
/**
* @brief Function for setting the address to be used in TWI transfers.
*
* @param[in] p_twi TWI instance.
* @param[in] address Address to be used in transfers.
*/
__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t address);
/**
* @brief Function for reading data received by TWI.
*
* @param[in] p_twi TWI instance.
*
* @return Received data.
*/
__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi);
/**
* @brief Function for writing data to be transmitted by TWI.
*
* @param[in] p_twi TWI instance.
* @param[in] data Data to be transmitted.
*/
__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data);
__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi,
uint32_t shorts_mask);
/**
* @}
*/
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_twi,
nrf_twi_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi,
nrf_twi_task_t task)
{
return (uint32_t *)((uint8_t *)p_twi + (uint32_t)task);
}
__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi,
nrf_twi_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_twi,
nrf_twi_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi,
nrf_twi_event_t event)
{
return (uint32_t *)((uint8_t *)p_twi + (uint32_t)event);
}
__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_twi,
uint32_t shorts_mask)
{
p_twi->SHORTS |= shorts_mask;
}
__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_twi,
uint32_t shorts_mask)
{
p_twi->SHORTS &= ~(shorts_mask);
}
__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi,
uint32_t int_mask)
{
p_twi->INTENSET = int_mask;
}
__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi,
uint32_t int_mask)
{
p_twi->INTENCLR = int_mask;
}
__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_twi,
nrf_twi_int_mask_t int_mask)
{
return (bool)(p_twi->INTENSET & int_mask);
}
__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi)
{
p_twi->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi)
{
p_twi->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi,
uint32_t scl_pin,
uint32_t sda_pin)
{
p_twi->PSELSCL = scl_pin;
p_twi->PSELSDA = sda_pin;
}
__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi,
nrf_twi_frequency_t frequency)
{
p_twi->FREQUENCY = frequency;
}
__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_twi)
{
uint32_t error_source = p_twi->ERRORSRC;
// [error flags are cleared by writing '1' on their position]
p_twi->ERRORSRC = error_source;
return error_source;
}
__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t address)
{
p_twi->ADDRESS = address;
}
__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi)
{
return (uint8_t)p_twi->RXD;
}
__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data)
{
p_twi->TXD = data;
}
__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi,
uint32_t shorts_mask)
{
p_twi->SHORTS = shorts_mask;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_TWI_H__

View File

@ -0,0 +1,478 @@
/* 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_TWIM_H__
#define NRF_TWIM_H__
/**
* @defgroup nrf_twim_hal TWIM HAL
* @{
* @ingroup nrf_twi_master
*
* @brief Hardware access layer for managing the TWIM peripheral.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "nrf.h"
/**
* @brief TWIM tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TWIM_TASK_STARTRX = offsetof(NRF_TWIM_Type, TASKS_STARTRX), ///< Start TWI receive sequence.
NRF_TWIM_TASK_STARTTX = offsetof(NRF_TWIM_Type, TASKS_STARTTX), ///< Start TWI transmit sequence.
NRF_TWIM_TASK_STOP = offsetof(NRF_TWIM_Type, TASKS_STOP), ///< Stop TWI transaction.
NRF_TWIM_TASK_SUSPEND = offsetof(NRF_TWIM_Type, TASKS_SUSPEND), ///< Suspend TWI transaction.
NRF_TWIM_TASK_RESUME = offsetof(NRF_TWIM_Type, TASKS_RESUME) ///< Resume TWI transaction.
/*lint -restore*/
} nrf_twim_task_t;
/**
* @brief TWIM events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_TWIM_EVENT_STOPPED = offsetof(NRF_TWIM_Type, EVENTS_STOPPED), ///< TWI stopped.
NRF_TWIM_EVENT_ERROR = offsetof(NRF_TWIM_Type, EVENTS_ERROR), ///< TWI error.
NRF_TWIM_EVENT_SUSPENDED = 0x148, ///< TWI suspended.
NRF_TWIM_EVENT_RXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_RXSTARTED), ///< Receive sequence started.
NRF_TWIM_EVENT_TXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_TXSTARTED), ///< Transmit sequence started.
NRF_TWIM_EVENT_LASTRX = offsetof(NRF_TWIM_Type, EVENTS_LASTRX), ///< Byte boundary, starting to receive the last byte.
NRF_TWIM_EVENT_LASTTX = offsetof(NRF_TWIM_Type, EVENTS_LASTTX) ///< Byte boundary, starting to transmit the last byte.
/*lint -restore*/
} nrf_twim_event_t;
/**
* @brief TWIM shortcuts.
*/
typedef enum
{
NRF_TWIM_SHORT_LASTTX_STARTRX_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk, ///< Shortcut between LASTTX event and STARTRX task.
NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK = TWIM_SHORTS_LASTTX_SUSPEND_Msk, ///< Shortcut between LASTTX event and SUSPEND task.
NRF_TWIM_SHORT_LASTTX_STOP_MASK = TWIM_SHORTS_LASTTX_STOP_Msk, ///< Shortcut between LASTTX event and STOP task.
NRF_TWIM_SHORT_LASTRX_STARTTX_MASK = TWIM_SHORTS_LASTRX_STARTTX_Msk, ///< Shortcut between LASTRX event and STARTTX task.
NRF_TWIM_SHORT_LASTRX_STOP_MASK = TWIM_SHORTS_LASTRX_STOP_Msk ///< Shortcut between LASTRX event and STOP task.
} nrf_twim_short_mask_t;
/**
* @brief TWIM interrupts.
*/
typedef enum
{
NRF_TWIM_INT_STOPPED_MASK = TWIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
NRF_TWIM_INT_ERROR_MASK = TWIM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
NRF_TWIM_INT_SUSPENDED_MASK = (1 << 18), ///< Interrupt on SUSPENDED event.
NRF_TWIM_INT_RXSTARTED_MASK = TWIM_INTENSET_RXSTARTED_Msk, ///< Interrupt on RXSTARTED event.
NRF_TWIM_INT_TXSTARTED_MASK = TWIM_INTENSET_TXSTARTED_Msk, ///< Interrupt on TXSTARTED event.
NRF_TWIM_INT_LASTRX_MASK = TWIM_INTENSET_LASTRX_Msk, ///< Interrupt on LASTRX event.
NRF_TWIM_INT_LASTTX_MASK = TWIM_INTENSET_LASTTX_Msk ///< Interrupt on LASTTX event.
} nrf_twim_int_mask_t;
/**
* @brief TWIM master clock frequency.
*/
typedef enum
{
NRF_TWIM_FREQ_100K = TWIM_FREQUENCY_FREQUENCY_K100, ///< 100 kbps.
NRF_TWIM_FREQ_250K = TWIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
NRF_TWIM_FREQ_400K = TWIM_FREQUENCY_FREQUENCY_K400 ///< 400 kbps.
} nrf_twim_frequency_t;
/**
* @brief TWIM error source.
*/
typedef enum
{
NRF_TWIM_ERROR_ADDRESS_NACK = TWIM_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address.
NRF_TWIM_ERROR_DATA_NACK = TWIM_ERRORSRC_DNACK_Msk ///< NACK received after sending a data byte.
} nrf_twim_error_t;
/**
* @brief Function for activating a specific TWIM task.
*
* @param[in] p_twim TWIM instance.
* @param[in] task Task to activate.
*/
__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_twim,
nrf_twim_task_t task);
/**
* @brief Function for getting the address of a specific TWIM task register.
*
* @param[in] p_twim TWIM instance.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_twim,
nrf_twim_task_t task);
/**
* @brief Function for clearing a specific TWIM event.
*
* @param[in] p_twim TWIM instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event);
/**
* @brief Function for checking the state of a specific TWIM event.
*
* @param[in] p_twim TWIM instance.
* @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_twim_event_check(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event);
/**
* @brief Function for getting the address of a specific TWIM event register.
*
* @param[in] p_twim TWIM instance.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event);
/**
* @brief Function for enabling specified shortcuts.
*
* @param[in] p_twim TWIM instance.
* @param[in] shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask);
/**
* @brief Function for disabling specified shortcuts.
*
* @param[in] p_twim TWIM instance.
* @param[in] shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_twim TWIM instance.
* @param[in] int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_twim,
uint32_t int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_twim TWIM instance.
* @param[in] int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_twim,
uint32_t int_mask);
/**
* @brief Function for checking the state of a given interrupt.
*
* @param[in] p_twim TWIM instance.
* @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_twim_int_enable_check(NRF_TWIM_Type * p_twim,
nrf_twim_int_mask_t int_mask);
/**
* @brief Function for enabling the TWIM peripheral.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_twim);
/**
* @brief Function for disabling the TWIM peripheral.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_twim);
/**
* @brief Function for configuring TWI pins.
*
*
* @param[in] p_twim TWIM instance.
* @param[in] scl_pin SCL pin number.
* @param[in] sda_pin SDA pin number.
*/
__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_twim,
uint32_t scl_pin,
uint32_t sda_pin);
/**
* @brief Function for setting the TWI master clock frequency.
*
* @param[in] p_twim TWIM instance.
* @param[in] frequency TWI frequency.
*/
__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_twim,
nrf_twim_frequency_t frequency);
/**
* @brief Function for checking the TWI error source.
*
* The error flags are cleared after reading.
*
* @param[in] p_twim TWIM instance.
*
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_twim);
/**
* @brief Function for setting the address to be used in TWI transfers.
*
* @param[in] p_twim TWIM instance.
* @param[in] address Address to be used in transfers.
*/
__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_twim,
uint8_t address);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_twim TWIM instance.
* @param[in] p_buffer Pointer to the buffer with data to send.
* @param[in] length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_twim,
uint8_t const * p_buffer,
uint8_t length);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_twim TWIM instance.
* @param[in] p_buffer Pointer to the buffer for received data.
* @param[in] length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_twim,
uint8_t * p_buffer,
uint8_t length);
__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask);
__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_twim);
__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_twim);
/**
* @brief Function for enabling the TX list feature.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_twim);
/**
* @brief Function for disabling the TX list feature.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_twim);
/**
* @brief Function for enabling the RX list feature.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_twim);
/**
* @brief Function for disabling the RX list feature.
*
* @param[in] p_twim TWIM instance.
*/
__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_twim);
/**
* @}
*/
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_twim,
nrf_twim_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_twim,
nrf_twim_task_t task)
{
return (uint32_t *)((uint8_t *)p_twim + (uint32_t)task);
}
__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_twim,
nrf_twim_event_t event)
{
return (uint32_t *)((uint8_t *)p_twim + (uint32_t)event);
}
__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask)
{
p_twim->SHORTS |= shorts_mask;
}
__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask)
{
p_twim->SHORTS &= ~(shorts_mask);
}
__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_twim,
uint32_t int_mask)
{
p_twim->INTENSET = int_mask;
}
__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_twim,
uint32_t int_mask)
{
p_twim->INTENCLR = int_mask;
}
__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_twim,
nrf_twim_int_mask_t int_mask)
{
return (bool)(p_twim->INTENSET & int_mask);
}
__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_twim)
{
p_twim->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_twim)
{
p_twim->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_twim,
uint32_t scl_pin,
uint32_t sda_pin)
{
p_twim->PSEL.SCL = scl_pin;
p_twim->PSEL.SDA = sda_pin;
}
__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_twim,
nrf_twim_frequency_t frequency)
{
p_twim->FREQUENCY = frequency;
}
__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_twim)
{
uint32_t error_source = p_twim->ERRORSRC;
// [error flags are cleared by writing '1' on their position]
p_twim->ERRORSRC = error_source;
return error_source;
}
__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_twim,
uint8_t address)
{
p_twim->ADDRESS = address;
}
__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_twim,
uint8_t const * p_buffer,
uint8_t length)
{
p_twim->TXD.PTR = (uint32_t)p_buffer;
p_twim->TXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_twim,
uint8_t * p_buffer,
uint8_t length)
{
p_twim->RXD.PTR = (uint32_t)p_buffer;
p_twim->RXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_twim,
uint32_t shorts_mask)
{
p_twim->SHORTS = shorts_mask;
}
__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_twim)
{
return p_twim->TXD.AMOUNT;
}
__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_twim)
{
return p_twim->RXD.AMOUNT;
}
__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_twim)
{
p_twim->TXD.LIST = 1;
}
__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_twim)
{
p_twim->TXD.LIST = 0;
}
__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_twim)
{
p_twim->RXD.LIST = 1;
}
__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_twim)
{
p_twim->RXD.LIST = 0;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#endif // NRF_TWIM_H__

View File

@ -0,0 +1,676 @@
/* 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.
*
*/
/**
* @ingroup nrf_twis
* @defgroup nrf_twis_hal TWIS HAL
* @{
*
* @brief @tagAPI52 Hardware access layer for Two Wire Interface Slave with EasyDMA
* (TWIS) peripheral.
*/
#ifndef NRF_TWIS_H__
#define NRF_TWIS_H__
#include "nrf.h"
#include "nrf_drv_config.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
/**
* @brief TWIS tasks
*/
typedef enum
{
/*lint -save -e30*/
#ifndef NRF52_PAN_30 /* STOP task is not functional in MPW3 (PAN-30) */
/* Stop task is not working properly for first release */
NRF_TWIS_TASK_STOP = offsetof(NRF_TWIS_Type, TASKS_STOP), /**< Stop TWIS transaction */
#endif
NRF_TWIS_TASK_SUSPEND = offsetof(NRF_TWIS_Type, TASKS_SUSPEND), /**< Suspend TWIS transaction */
NRF_TWIS_TASK_RESUME = offsetof(NRF_TWIS_Type, TASKS_RESUME), /**< Resume TWIS transaction */
NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), /**< Prepare the TWIS slave to respond to a write command */
NRF_TWIS_TASK_PREPARETX = offsetof(NRF_TWIS_Type, TASKS_PREPARETX) /**< Prepare the TWIS slave to respond to a read command */
/*lint -restore*/
} nrf_twis_task_t;
/**
* @brief TWIS events
*/
typedef enum
{
/*lint -save -e30*/
NRF_TWIS_EVENT_STOPPED = offsetof(NRF_TWIS_Type, EVENTS_STOPPED), /**< TWIS stopped */
NRF_TWIS_EVENT_ERROR = offsetof(NRF_TWIS_Type, EVENTS_ERROR), /**< TWIS error */
NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_RXSTARTED), /**< Receive sequence started */
NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_TXSTARTED), /**< Transmit sequence started */
NRF_TWIS_EVENT_WRITE = offsetof(NRF_TWIS_Type, EVENTS_WRITE), /**< Write command received */
NRF_TWIS_EVENT_READ = offsetof(NRF_TWIS_Type, EVENTS_READ) /**< Read command received */
/*lint -restore*/
} nrf_twis_event_t;
/**
* @brief TWIS shortcuts
*/
typedef enum
{
NRF_TWIS_SHORT_WRITE_SUSPEND_MASK = TWIS_SHORTS_WRITE_SUSPEND_Msk, /**< Shortcut between WRITE event and SUSPEND task */
NRF_TWIS_SHORT_READ_SUSPEND_MASK = TWIS_SHORTS_READ_SUSPEND_Msk, /**< Shortcut between READ event and SUSPEND task */
} nrf_twis_short_mask_t;
/**
* @brief TWIS interrupts
*/
typedef enum
{
NRF_TWIS_INT_STOPPED_MASK = TWIS_INTEN_STOPPED_Msk, /**< Interrupt on STOPPED event */
NRF_TWIS_INT_ERROR_MASK = TWIS_INTEN_ERROR_Msk, /**< Interrupt on ERROR event */
NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_RXSTARTED_Msk, /**< Interrupt on RXSTARTED event */
NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_TXSTARTED_Msk, /**< Interrupt on TXSTARTED event */
NRF_TWIS_INT_WRITE_MASK = TWIS_INTEN_WRITE_Msk, /**< Interrupt on WRITE event */
NRF_TWIS_INT_READ_MASK = TWIS_INTEN_READ_Msk, /**< Interrupt on READ event */
} nrf_twis_int_mask_t;
/**
* @brief TWIS error source
*/
typedef enum
{
NRF_TWIS_ERROR_OVERFLOW = TWIS_ERRORSRC_OVERFLOW_Msk, /**< RX buffer overflow detected, and prevented */
#ifdef NRF52_PAN_29
/* Patched version of bit positions in ERRORSRC register (PAN-29) */
NRF_TWIS_ERROR_DATA_NACK = 1U << 1, /**< NACK sent after receiving a data byte */
NRF_TWIS_ERROR_OVERREAD = 1U << 2 /**< TX buffer over-read detected, and prevented */
#else
/* Code that meets current documentation */
NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk, /**< NACK sent after receiving a data byte */
NRF_TWIS_ERROR_OVERREAD = TWIS_ERRORSRC_OVERREAD_Msk /**< TX buffer over-read detected, and prevented */
#endif
} nrf_twis_error_t;
/**
* @brief TWIS address matching configuration
*/
typedef enum
{
NRF_TWIS_CONFIG_ADDRESS0_MASK = TWIS_CONFIG_ADDRESS0_Msk, /**< Enable or disable address matching on ADDRESS[0] */
NRF_TWIS_CONFIG_ADDRESS1_MASK = TWIS_CONFIG_ADDRESS1_Msk, /**< Enable or disable address matching on ADDRESS[1] */
NRF_TWIS_CONFIG_ADDRESS01_MASK = TWIS_CONFIG_ADDRESS0_Msk | TWIS_CONFIG_ADDRESS1_Msk /**< Enable both address matching */
} nrf_twis_config_addr_mask_t;
/**
* @brief Variable type to hold amount of data for EasyDMA
*
* Variable of the minimum size that can hold the amount of data to transfer.
*
* @note
* Defined to make it simple to change if EasyDMA would be updated to support more data in
* the future devices to.
*/
typedef uint8_t nrf_twis_amount_t;
/**
* @brief Smallest variable type to hold TWI address
*
* Variable of the minimum size that can hold single TWI address.
*
* @note
* Defined to make it simple to change if new TWI would support for example
* 10 bit addressing mode.
*/
typedef uint8_t nrf_twis_address_t;
/**
* @brief Function for activating a specific TWIS task.
*
* @param[in] p_twis TWIS instance.
* @param task Task.
*/
__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task);
/**
* @brief Function for returning the address of a specific TWIS task register.
*
* @param[in] p_twis TWIS instance.
* @param task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrf_twis_task_address_get(
NRF_TWIS_Type const * const p_twis,
nrf_twis_task_t task);
/**
* @brief Function for clearing a specific event.
*
* @param[in] p_twis TWIS instance.
* @param event Event.
*/
__STATIC_INLINE void nrf_twis_event_clear(
NRF_TWIS_Type * const p_twis,
nrf_twis_event_t event);
/**
* @brief Function for returning the state of a specific event.
*
* @param[in] p_twis TWIS instance.
* @param event Event.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_twis_event_check(
NRF_TWIS_Type const * const p_twis,
nrf_twis_event_t event);
/**
* @brief Function for getting and clearing the state of specific event
*
* This function checks the state of the event and clears it.
* @param[in,out] p_twis TWIS instance
* @param event Event.
*
* @retval true If the event was set.
* @retval false If the event was not set.
*/
__STATIC_INLINE bool nrf_twis_event_get_and_clear(
NRF_TWIS_Type * const p_twis,
nrf_twis_event_t event);
/**
* @brief Function for returning the address of a specific TWIS event register.
*
* @param[in] p_twis TWIS instance.
* @param event Event.
*
* @return Address.
*/
__STATIC_INLINE uint32_t nrf_twis_event_address_get(
NRF_TWIS_Type const * const p_twis,
nrf_twis_event_t event);
/**
* @brief Function for setting a shortcut.
*
* @param[in] p_twis TWIS instance.
* @param short_mask Shortcuts mask.
*/
__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask);
/**
* @brief Function for clearing shortcuts.
*
* @param[in] p_twis TWIS instance.
* @param short_mask Shortcuts mask.
*/
__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask);
/**
* @brief Get the shorts mask
*
* Function returns shorts register.
* @param[in] p_twis TWIS instance.
* @return Flags of currently enabled shortcuts
*/
__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis);
/**
* @brief Function for enabling selected interrupts.
*
* @param[in] p_twis TWIS instance.
* @param int_mask Interrupts mask.
*/
__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask);
/**
* @brief Function for retrieving the state of selected interrupts.
*
* @param[in] p_twis TWIS instance.
* @param int_mask Interrupts mask.
*
* @retval true If any of selected interrupts is enabled.
* @retval false If none of selected interrupts is enabled.
*/
__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask);
/**
* @brief Function for disabling selected interrupts.
*
* @param[in] p_twis TWIS instance.
* @param int_mask Interrupts mask.
*/
__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask);
/**
* @brief Function for retrieving and clearing the TWIS error source.
*
* @attention Error sources are cleared after read.
* @param[in] p_twis TWIS instance
* @return Error source mask with values from @ref nrf_twis_error_t.
*/
__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis);
/**
* @brief Get information which of addresses matched
*
* Function returns index in the address table
* that points to the address that already matched.
* @param[in] p_twis TWIS instance
* @return Index of matched address
*/
__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis);
/**
* @brief Function for enabling TWIS.
*
* @param[in] p_twis TWIS instance.
*/
__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_twis);
/**
* @brief Function for disabling TWIS.
*
* @param[in] p_twis TWIS instance.
*/
__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_twis);
/**
* @brief Function for configuring TWIS pins.
*
* @param[in] p_twis TWIS instance.
* @param scl SCL pin number.
* @param sda SDA pin number.
*/
__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_twis TWIS instance.
* @param p_buf Pointer to the buffer for received data.
* @param length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_twis_rx_buffer_set(
NRF_TWIS_Type * const p_twis,
uint8_t * p_buf,
nrf_twis_amount_t length);
/**
* @brief Function that prepares TWIS for receiving
*
* This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task.
* @param[in] p_twis TWIS instance.
* @param p_buf Pointer to the buffer for received data.
* @param length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_twis_rx_prepare(
NRF_TWIS_Type * const p_twis,
uint8_t * p_buf,
nrf_twis_amount_t length);
/**
* @brief Function for getting number of bytes received in the last transaction.
*
* @param[in] p_twis TWIS instance.
* @return Amount of bytes received.
* */
__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_twis TWIS instance.
* @param p_buf Pointer to the buffer with data to send.
* @param length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_twis_tx_buffer_set(
NRF_TWIS_Type * const p_twis,
uint8_t const * p_buf,
nrf_twis_amount_t length);
/**
* @brief Function that prepares TWIS for transmitting
*
* This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task.
* @param[in] p_twis TWIS instance.
* @param p_buf Pointer to the buffer with data to send.
* @param length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_twis_tx_prepare(
NRF_TWIS_Type * const p_twis,
uint8_t const * p_buf,
nrf_twis_amount_t length);
/**
* @brief Function for getting number of bytes transmitted in the last transaction.
*
* @param[in] p_twis TWIS instance.
* @return Amount of bytes transmitted.
*/
__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis);
/**
* @brief Function for setting slave address
*
* Function sets the selected address for this TWI interface.
* @param[in] p_twis TWIS instance.
* @param n Index of address to set
* @param addr Addres to set
* @sa nrf_twis_config_address_set
* @sa nrf_twis_config_address_get
*/
__STATIC_INLINE void nrf_twis_address_set(
NRF_TWIS_Type * const p_twis,
uint_fast8_t n,
nrf_twis_address_t addr);
/**
* @brief Function for retrieving configured slave address
*
* Function gets the selected address for this TWI interface.
* @param[in] p_twis TWIS instance.
* @param n Index of address to get
*/
__STATIC_INLINE nrf_twis_address_t nrf_twis_address_get(
NRF_TWIS_Type const * const p_twis,
uint_fast8_t n);
/**
* @brief Function for setting the device address configuration.
*
* @param[in] p_twis TWIS instance.
* @param addr_mask Mask of address indexes of what device should answer to.
*
* @sa nrf_twis_address_set
*/
__STATIC_INLINE void nrf_twis_config_address_set(
NRF_TWIS_Type * const p_twis,
nrf_twis_config_addr_mask_t addr_mask);
/**
* @brief Function for retrieving the device address configuration.
*
* @param[in] p_twis TWIS instance.
*
* @return Mask of address indexes of what device should answer to.
*/
__STATIC_INLINE nrf_twis_config_addr_mask_t nrf_twis_config_address_get(
NRF_TWIS_Type const * const p_twis);
/**
* @brief Function for setting the over-read character.
*
* @param[in] p_twis TWIS instance.
* @param[in] orc Over-read character. Character clocked out in case of
* over-read of the TXD buffer.
*/
__STATIC_INLINE void nrf_twis_orc_set(
NRF_TWIS_Type * const p_twis,
uint8_t orc);
/**
* @brief Function for setting the over-read character.
*
* @param[in] p_twis TWIS instance.
*
* @return Over-read character configured for selected instance.
*/
__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis);
/** @} */ /* End of nrf_twis_hal */
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
/* ------------------------------------------------------------------------------------------------
* Internal functions
*/
/**
* @internal
* @brief Internal function for getting task/event register address
*
* @param[in] p_twis TWIS instance.
* @oaram offset Offset of the register from the instance beginning
*
* @attention offset has to be modulo 4 value. In other case we can get hardware fault.
* @return Pointer to the register
*/
__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_twis, uint32_t offset)
{
return (volatile uint32_t*)((uint8_t *)p_twis + (uint32_t)offset);
}
/**
* @internal
* @brief Internal function for getting task/event register address - constant version
*
* @param[in] p_twis TWIS instance.
* @oaram offset Offset of the register from the instance beginning
*
* @attention offset has to be modulo 4 value. In other case we can get hardware fault.
* @return Pointer to the register
*/
__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_twis, uint32_t offset)
{
return (volatile const uint32_t*)((uint8_t *)p_twis + (uint32_t)offset);
}
/* ------------------------------------------------------------------------------------------------
* Interface functions definitions
*/
void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task)
{
*(nrf_twis_getRegPtr(p_twis, (uint32_t)task)) = 1UL;
}
uint32_t nrf_twis_task_address_get(
NRF_TWIS_Type const * const p_twis,
nrf_twis_task_t task)
{
return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)task);
}
void nrf_twis_event_clear(
NRF_TWIS_Type * const p_twis,
nrf_twis_event_t event)
{
*(nrf_twis_getRegPtr(p_twis, (uint32_t)event)) = 0UL;
}
bool nrf_twis_event_check(
NRF_TWIS_Type const * const p_twis,
nrf_twis_event_t event)
{
return (bool)*nrf_twis_getRegPtr_c(p_twis, (uint32_t)event);
}
bool nrf_twis_event_get_and_clear(
NRF_TWIS_Type * const p_twis,
nrf_twis_event_t event)
{
bool ret = nrf_twis_event_check(p_twis, event);
if(ret)
{
nrf_twis_event_clear(p_twis, event);
}
return ret;
}
uint32_t nrf_twis_event_address_get(
NRF_TWIS_Type const * const p_twis,
nrf_twis_event_t event)
{
return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)event);
}
void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask)
{
p_twis->SHORTS |= short_mask;
}
void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask)
{
if(~0U == short_mask)
{
/* Optimized version for "disable all" */
p_twis->SHORTS = 0;
}
else
{
p_twis->SHORTS &= ~short_mask;
}
}
uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis)
{
return p_twis->SHORTS;
}
void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask)
{
p_twis->INTENSET = int_mask;
}
bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask)
{
return (bool)(p_twis->INTENSET & int_mask);
}
void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask)
{
p_twis->INTENCLR = int_mask;
}
uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis)
{
uint32_t ret = p_twis->ERRORSRC;
p_twis->ERRORSRC = ret;
return ret;
}
uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis)
{
return (uint_fast8_t)p_twis->MATCH;
}
void nrf_twis_enable(NRF_TWIS_Type * const p_twis)
{
p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos);
}
void nrf_twis_disable(NRF_TWIS_Type * const p_twis)
{
p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos);
}
void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda)
{
p_twis->PSEL.SCL = scl;
p_twis->PSEL.SDA = sda;
}
void nrf_twis_rx_buffer_set(
NRF_TWIS_Type * const p_twis,
uint8_t * p_buf,
nrf_twis_amount_t length)
{
p_twis->RXD.PTR = (uint32_t)p_buf;
p_twis->RXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twis_rx_prepare(
NRF_TWIS_Type * const p_twis,
uint8_t * p_buf,
nrf_twis_amount_t length)
{
nrf_twis_rx_buffer_set(p_twis, p_buf, length);
nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARERX);
}
nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis)
{
return (nrf_twis_amount_t)p_twis->RXD.AMOUNT;
}
void nrf_twis_tx_buffer_set(
NRF_TWIS_Type * const p_twis,
uint8_t const * p_buf,
nrf_twis_amount_t length)
{
p_twis->TXD.PTR = (uint32_t)p_buf;
p_twis->TXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twis_tx_prepare(
NRF_TWIS_Type * const p_twis,
uint8_t const * p_buf,
nrf_twis_amount_t length)
{
nrf_twis_tx_buffer_set(p_twis, p_buf, length);
nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARETX);
}
nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis)
{
return (nrf_twis_amount_t)p_twis->TXD.AMOUNT;
}
void nrf_twis_address_set(
NRF_TWIS_Type * const p_twis,
uint_fast8_t n,
nrf_twis_address_t addr)
{
p_twis->ADDRESS[n] = addr;
}
nrf_twis_address_t nrf_twis_address_get(
NRF_TWIS_Type const * const p_twis,
uint_fast8_t n)
{
return (nrf_twis_address_t)p_twis->ADDRESS[n];
}
void nrf_twis_config_address_set(
NRF_TWIS_Type * const p_twis,
nrf_twis_config_addr_mask_t addr_mask)
{
/* This is the only configuration in TWIS - just write it without masking */
p_twis->CONFIG = addr_mask;
}
nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_twis)
{
return (nrf_twis_config_addr_mask_t)(p_twis->CONFIG & TWIS_ADDRESS_ADDRESS_Msk);
}
void nrf_twis_orc_set(
NRF_TWIS_Type * const p_twis,
uint8_t orc)
{
p_twis->ORC = orc;
}
uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis)
{
return (uint8_t)p_twis->ORC;
}
#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
#endif /* NRF_TWIS_H__ */

View File

@ -0,0 +1,471 @@
/* 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_UART_H__
#define NRF_UART_H__
#include "nrf.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
/**
* @defgroup nrf_uart_hal UART HAL
* @{
* @ingroup nrf_uart
*
* @brief Hardware access layer for accessing the UART peripheral.
*/
#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF
/**
* @enum nrf_uart_task_t
* @brief UART tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_UART_TASK_STARTRX = offsetof(NRF_UART_Type, TASKS_STARTRX), /**< Task for starting reception. */
NRF_UART_TASK_STOPRX = offsetof(NRF_UART_Type, TASKS_STOPRX), /**< Task for stopping reception. */
NRF_UART_TASK_STARTTX = offsetof(NRF_UART_Type, TASKS_STARTTX), /**< Task for starting transmission. */
NRF_UART_TASK_STOPTX = offsetof(NRF_UART_Type, TASKS_STOPTX), /**< Task for stopping transmission. */
NRF_UART_TASK_SUSPEND = offsetof(NRF_UART_Type, TASKS_SUSPEND), /**< Task for suspending UART. */
/*lint -restore*/
} nrf_uart_task_t;
/**
* @enum nrf_uart_event_t
* @brief UART events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_UART_EVENT_CTS = offsetof(NRF_UART_Type, EVENTS_CTS), /**< Event from CTS line activation. */
NRF_UART_EVENT_NCTS = offsetof(NRF_UART_Type, EVENTS_NCTS), /**< Event from CTS line deactivation. */
NRF_UART_EVENT_RXDRDY = offsetof(NRF_UART_Type, EVENTS_RXDRDY),/**< Event from data ready in RXD. */
NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */
NRF_UART_EVENT_ERROR = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */
NRF_UART_EVENT_RXTO = offsetof(NRF_UART_Type, EVENTS_RXTO) /**< Event from receiver timeout. */
/*lint -restore*/
} nrf_uart_event_t;
/**
* @enum nrf_uart_int_mask_t
* @brief UART interrupts.
*/
typedef enum
{
/*lint -save -e30*/
NRF_UART_INT_MASK_CTS = UART_INTENCLR_CTS_Msk, /**< CTS line activation interrupt. */
NRF_UART_INT_MASK_NCTS = UART_INTENCLR_NCTS_Msk, /**< CTS line deactivation interrupt. */
NRF_UART_INT_MASK_RXDRDY = UART_INTENCLR_RXDRDY_Msk, /**< Data ready in RXD interrupt. */
NRF_UART_INT_MASK_TXDRDY = UART_INTENCLR_TXDRDY_Msk, /**< Data sent from TXD interrupt. */
NRF_UART_INT_MASK_ERROR = UART_INTENCLR_ERROR_Msk, /**< Error detection interrupt. */
NRF_UART_INT_MASK_RXTO = UART_INTENCLR_RXTO_Msk /**< Receiver timeout interrupt. */
/*lint -restore*/
} nrf_uart_int_mask_t;
/**
* @enum nrf_uart_baudrate_t
* @brief Baudrates supported by UART.
*/
typedef enum
{
#ifdef NRF52
NRF_UART_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */
NRF_UART_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */
NRF_UART_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */
NRF_UART_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */
NRF_UART_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */
NRF_UART_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */
NRF_UART_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */
NRF_UART_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */
NRF_UART_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */
NRF_UART_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */
NRF_UART_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */
NRF_UART_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */
NRF_UART_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */
NRF_UART_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */
NRF_UART_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */
NRF_UART_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */
#else
NRF_UART_BAUDRATE_1200 = UART_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */
NRF_UART_BAUDRATE_2400 = UART_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */
NRF_UART_BAUDRATE_4800 = UART_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */
NRF_UART_BAUDRATE_9600 = UART_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */
NRF_UART_BAUDRATE_14400 = UART_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */
NRF_UART_BAUDRATE_19200 = UART_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */
NRF_UART_BAUDRATE_28800 = UART_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */
NRF_UART_BAUDRATE_38400 = UART_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */
NRF_UART_BAUDRATE_57600 = UART_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */
NRF_UART_BAUDRATE_76800 = UART_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */
NRF_UART_BAUDRATE_115200 = UART_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */
NRF_UART_BAUDRATE_230400 = UART_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */
NRF_UART_BAUDRATE_250000 = UART_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */
NRF_UART_BAUDRATE_460800 = UART_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */
NRF_UART_BAUDRATE_921600 = UART_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */
NRF_UART_BAUDRATE_1000000 = UART_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */
#endif
} nrf_uart_baudrate_t;
/**
* @enum nrf_uart_error_mask_t
* @brief Types of UART error masks.
*/
typedef enum
{
NRF_UART_ERROR_OVERRUN_MASK = UART_ERRORSRC_OVERRUN_Msk, /**< Overrun error. */
NRF_UART_ERROR_PARITY_MASK = UART_ERRORSRC_PARITY_Msk, /**< Parity error. */
NRF_UART_ERROR_FRAMING_MASK = UART_ERRORSRC_FRAMING_Msk, /**< Framing error. */
NRF_UART_ERROR_BREAK_MASK = UART_ERRORSRC_BREAK_Msk, /**< Break error. */
} nrf_uart_error_mask_t;
/**
* @enum nrf_uart_parity_t
* @brief Types of UART parity modes.
*/
typedef enum
{
NRF_UART_PARITY_EXCLUDED = UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos, /**< Parity excluded. */
NRF_UART_PARITY_INCLUDED = UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos, /**< Parity included. */
} nrf_uart_parity_t;
/**
* @enum nrf_uart_hwfc_t
* @brief Types of UART flow control modes.
*/
typedef enum
{
NRF_UART_HWFC_DISABLED = UART_CONFIG_HWFC_Disabled, /**< HW flow control disabled. */
NRF_UART_HWFC_ENABLED = UART_CONFIG_HWFC_Enabled, /**< HW flow control enabled. */
} nrf_uart_hwfc_t;
/**
* @brief Function for clearing a specific UART event.
*
* @param[in] p_reg UART instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event);
/**
* @brief Function for checking the state of a specific UART event.
*
* @param[in] p_reg UART instance.
* @param[in] event Event to check.
*
* @retval True if event is set, False otherwise.
*/
__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event);
/**
* @brief Function for returning the address of a specific UART event register.
*
* @param[in] p_reg UART instance.
* @param[in] event Desired event.
*
* @retval Address of specified event register.
*/
__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg,
nrf_uart_event_t event);
/**
* @brief Function for enabling a specific interrupt.
*
* @param p_reg Instance.
* @param int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param p_reg Instance.
* @param int_mask Mask of interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for disabling specific interrupts.
*
* @param p_reg Instance.
* @param int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for getting error source mask. Function is clearing error source flags after reading.
*
* @param p_reg Instance.
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg);
/**
* @brief Function for enabling UART.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg);
/**
* @brief Function for disabling UART.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg);
/**
* @brief Function for configuring TX/RX pins.
*
* @param p_reg Instance.
* @param pseltxd TXD pin number.
* @param pselrxd RXD pin number.
*/
__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd);
/**
* @brief Function for disconnecting TX/RX pins.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg);
/**
* @brief Function for getting TX pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting RX pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting RTS pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting CTS pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for configuring flow control pins.
*
* @param p_reg Instance.
* @param pselrts RTS pin number.
* @param pselcts CTS pin number.
*/
__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg,
uint32_t pselrts,
uint32_t pselcts);
/**
* @brief Function for disconnecting flow control pins.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg);
/**
* @brief Function for reading RX data.
*
* @param p_reg Instance.
* @return Received byte.
*/
__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg);
/**
* @brief Function for setting Tx data.
*
* @param p_reg Instance.
* @param txd Byte.
*/
__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd);
/**
* @brief Function for starting an UART task.
*
* @param p_reg Instance.
* @param task Task.
*/
__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task);
/**
* @brief Function for returning the address of a specific task register.
*
* @param p_reg Instance.
* @param task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task);
/**
* @brief Function for configuring UART.
*
* @param p_reg Instance.
* @param hwfc Hardware flow control. Enabled if true.
* @param parity Parity. Included if true.
*/
__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg,
nrf_uart_parity_t parity,
nrf_uart_hwfc_t hwfc);
/**
* @brief Function for setting UART baudrate.
*
* @param p_reg Instance.
* @param baudrate Baudrate.
*/
__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg,
nrf_uart_event_t event)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENSET = int_mask;
}
__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask)
{
return (bool)(p_reg->INTENSET & int_mask);
}
__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENCLR = int_mask;
}
__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg)
{
uint32_t errsrc_mask = p_reg->ERRORSRC;
p_reg->ERRORSRC = errsrc_mask;
return errsrc_mask;
}
__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg)
{
p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled;
}
__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg)
{
p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled;
}
__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd)
{
p_reg->PSELTXD = pseltxd;
p_reg->PSELRXD = pselrxd;
}
__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg)
{
nrf_uart_txrx_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED);
}
__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg)
{
return p_reg->PSELTXD;
}
__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg)
{
return p_reg->PSELRXD;
}
__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg)
{
return p_reg->PSELRTS;
}
__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg)
{
return p_reg->PSELCTS;
}
__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts)
{
p_reg->PSELRTS = pselrts;
p_reg->PSELCTS = pselcts;
}
__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg)
{
nrf_uart_hwfc_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED);
}
__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg)
{
return p_reg->RXD;
}
__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd)
{
p_reg->TXD = txd;
}
__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task)
{
return (uint32_t)p_reg + (uint32_t)task;
}
__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg,
nrf_uart_parity_t parity,
nrf_uart_hwfc_t hwfc)
{
p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc;
}
__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate)
{
p_reg->BAUDRATE = baudrate;
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#endif //NRF_UART_H__

View File

@ -0,0 +1,534 @@
/* 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_UARTE_H__
#define NRF_UARTE_H__
#include "nrf.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF
/**
* @defgroup nrf_uarte_hal UARTE HAL
* @{
* @ingroup nrf_uart
*
* @brief Hardware access layer for accessing the UARTE peripheral.
*/
/**
* @enum nrf_uarte_task_t
* @brief UARTE tasks.
*/
typedef enum
{
/*lint -save -e30*/
NRF_UARTE_TASK_STARTRX = offsetof(NRF_UARTE_Type, TASKS_STARTRX),///< Start UART receiver.
NRF_UARTE_TASK_STOPRX = offsetof(NRF_UARTE_Type, TASKS_STOPRX), ///< Stop UART receiver.
NRF_UARTE_TASK_STARTTX = offsetof(NRF_UARTE_Type, TASKS_STARTTX),///< Start UART transmitter.
NRF_UARTE_TASK_STOPTX = offsetof(NRF_UARTE_Type, TASKS_STOPTX), ///< Stop UART transmitter.
NRF_UARTE_TASK_FLUSHRX = offsetof(NRF_UARTE_Type, TASKS_FLUSHRX) ///< Flush RX FIFO in RX buffer.
/*lint -restore*/
} nrf_uarte_task_t;
/**
* @enum nrf_uarte_event_t
* @brief UARTE events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_UARTE_EVENT_CTS = offsetof(NRF_UARTE_Type, EVENTS_CTS), ///< CTS is activated.
NRF_UARTE_EVENT_NCTS = offsetof(NRF_UARTE_Type, EVENTS_NCTS), ///< CTS is deactivated.
NRF_UARTE_EVENT_ENDRX = offsetof(NRF_UARTE_Type, EVENTS_ENDRX), ///< Receive buffer is filled up.
NRF_UARTE_EVENT_ENDTX = offsetof(NRF_UARTE_Type, EVENTS_ENDTX), ///< Last TX byte transmitted.
NRF_UARTE_EVENT_ERROR = offsetof(NRF_UARTE_Type, EVENTS_ERROR), ///< Error detected.
NRF_UARTE_EVENT_RXTO = offsetof(NRF_UARTE_Type, EVENTS_RXTO), ///< Receiver timeout.
NRF_UARTE_EVENT_RXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_RXSTARTED),///< Receiver has started.
NRF_UARTE_EVENT_TXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_TXSTARTED),///< Transmitter has started.
NRF_UARTE_EVENT_TXSTOPPED = offsetof(NRF_UARTE_Type, EVENTS_TXSTOPPED) ///< Transmitted stopped.
/*lint -restore*/
} nrf_uarte_event_t;
/**
* @brief Types of UARTE shortcuts.
*/
typedef enum
{
NRF_UARTE_SHORT_ENDRX_STARTRX = UARTE_SHORTS_ENDRX_STARTRX_Msk,///< Shortcut between ENDRX event and STARTRX task.
NRF_UARTE_SHORT_ENDRX_STOPRX = UARTE_SHORTS_ENDRX_STOPRX_Msk, ///< Shortcut between ENDRX event and STOPRX task.
} nrf_uarte_short_t;
/**
* @enum nrf_uarte_int_mask_t
* @brief UARTE interrupts.
*/
typedef enum
{
NRF_UARTE_INT_CTS_MASK = UARTE_INTENSET_CTS_Msk, ///< Interrupt on CTS event.
NRF_UARTE_INT_NCTSRX_MASK = UARTE_INTENSET_NCTS_Msk, ///< Interrupt on NCTS event.
NRF_UARTE_INT_ENDRX_MASK = UARTE_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
NRF_UARTE_INT_ENDTX_MASK = UARTE_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event.
NRF_UARTE_INT_ERROR_MASK = UARTE_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
NRF_UARTE_INT_RXTO_MASK = UARTE_INTENSET_RXTO_Msk, ///< Interrupt on RXTO event.
NRF_UARTE_INT_RXSTARTED_MASK = UARTE_INTENSET_RXSTARTED_Msk,///< Interrupt on RXSTARTED event.
NRF_UARTE_INT_TXSTARTED_MASK = UARTE_INTENSET_TXSTARTED_Msk,///< Interrupt on TXSTARTED event.
NRF_UARTE_INT_TXSTOPPED_MASK = UARTE_INTENSET_TXSTOPPED_Msk ///< Interrupt on TXSTOPPED event.
} nrf_uarte_int_mask_t;
/**
* @enum nrf_uarte_baudrate_t
* @brief Baudrates supported by UARTE.
*/
typedef enum
{
NRF_UARTE_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud.
NRF_UARTE_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud.
NRF_UARTE_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, ///< 4800 baud.
NRF_UARTE_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, ///< 9600 baud.
NRF_UARTE_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, ///< 14400 baud.
NRF_UARTE_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, ///< 19200 baud.
NRF_UARTE_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, ///< 28800 baud.
NRF_UARTE_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, ///< 38400 baud.
NRF_UARTE_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, ///< 57600 baud.
NRF_UARTE_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, ///< 76800 baud.
NRF_UARTE_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, ///< 115200 baud.
NRF_UARTE_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, ///< 230400 baud.
NRF_UARTE_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, ///< 250000 baud.
NRF_UARTE_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, ///< 460800 baud.
NRF_UARTE_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, ///< 921600 baud.
NRF_UARTE_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud.
} nrf_uarte_baudrate_t;
/**
* @enum nrf_uarte_error_mask_t
* @brief Types of UARTE error masks.
*/
typedef enum
{
NRF_UARTE_ERROR_OVERRUN_MASK = UARTE_ERRORSRC_OVERRUN_Msk, ///< Overrun error.
NRF_UARTE_ERROR_PARITY_MASK = UARTE_ERRORSRC_PARITY_Msk, ///< Parity error.
NRF_UARTE_ERROR_FRAMING_MASK = UARTE_ERRORSRC_FRAMING_Msk, ///< Framing error.
NRF_UARTE_ERROR_BREAK_MASK = UARTE_ERRORSRC_BREAK_Msk, ///< Break error.
} nrf_uarte_error_mask_t;
/**
* @enum nrf_uarte_parity_t
* @brief Types of UARTE parity modes.
*/
typedef enum
{
NRF_UARTE_PARITY_EXCLUDED = UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos, ///< Parity excluded.
NRF_UARTE_PARITY_INCLUDED = UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos, ///< Parity included.
} nrf_uarte_parity_t;
/**
* @enum nrf_uarte_hwfc_t
* @brief Types of UARTE flow control modes.
*/
typedef enum
{
NRF_UARTE_HWFC_DISABLED = UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control disabled.
NRF_UARTE_HWFC_ENABLED = UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control enabled.
} nrf_uarte_hwfc_t;
/**
* @brief Function for clearing a specific UARTE event.
*
* @param[in] p_reg UARTE instance.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);
/**
* @brief Function for checking the state of a specific UARTE event.
*
* @param[in] p_reg UARTE instance.
* @param[in] event Event to check.
*
* @retval True if event is set, False otherwise.
*/
__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);
/**
* @brief Function for returning the address of a specific UARTE event register.
*
* @param[in] p_reg UARTE instance.
* @param[in] event Desired event.
*
* @retval Address of specified event register.
*/
__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event);
/**
* @brief Function for enabling UARTE shortcuts.
*
* @param p_reg UARTE instance.
* @param shorts_mask Shortcuts to enable.
*/
__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask);
/**
* @brief Function for disabling UARTE shortcuts.
*
* @param p_reg UARTE instance.
* @param shorts_mask Shortcuts to disable.
*/
__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask);
/**
* @brief Function for enabling UARTE interrupts.
*
* @param p_reg Instance.
* @param int_mask Interrupts to enable.
*/
__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param p_reg Instance.
* @param int_mask Mask of interrupt to check.
*
* @retval true If the interrupt is enabled.
* @retval false If the interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask);
/**
* @brief Function for disabling specific interrupts.
*
* @param p_reg Instance.
* @param int_mask Interrupts to disable.
*/
__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for getting error source mask. Function is clearing error source flags after reading.
*
* @param p_reg Instance.
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg);
/**
* @brief Function for enabling UARTE.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg);
/**
* @brief Function for disabling UARTE.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg);
/**
* @brief Function for configuring TX/RX pins.
*
* @param p_reg Instance.
* @param pseltxd TXD pin number.
* @param pselrxd RXD pin number.
*/
__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd);
/**
* @brief Function for disconnecting TX/RX pins.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting TX pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting RX pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting RTS pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting CTS pin.
*
* @param p_reg Instance.
*/
__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for configuring flow control pins.
*
* @param p_reg Instance.
* @param pselrts RTS pin number.
* @param pselcts CTS pin number.
*/
__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg,
uint32_t pselrts,
uint32_t pselcts);
/**
* @brief Function for disconnecting flow control pins.
*
* @param p_reg Instance.
*/
__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg);
/**
* @brief Function for starting an UARTE task.
*
* @param p_reg Instance.
* @param task Task.
*/
__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task);
/**
* @brief Function for returning the address of a specific task register.
*
* @param p_reg Instance.
* @param task Task.
*
* @return Task address.
*/
__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task);
/**
* @brief Function for configuring UARTE.
*
* @param p_reg Instance.
* @param hwfc Hardware flow control. Enabled if true.
* @param parity Parity. Included if true.
*/
__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg,
nrf_uarte_parity_t parity,
nrf_uarte_hwfc_t hwfc);
/**
* @brief Function for setting UARTE baudrate.
*
* @param p_reg Instance.
* @param baudrate Baudrate.
*/
__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_reg Instance.
* @param[in] p_buffer Pointer to the buffer with data to send.
* @param[in] length Maximum number of data bytes to transmit.
*/
__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg,
uint8_t const * p_buffer,
uint8_t length);
/**
* @brief Function for getting number of bytes transmitted in the last transaction.
*
* @param[in] p_reg Instance.
*
* @retval Amount of bytes transmitted.
*/
__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_reg Instance.
* @param[in] p_buffer Pointer to the buffer for received data.
* @param[in] length Maximum number of data bytes to receive.
*/
__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg,
uint8_t * p_buffer,
uint8_t length);
/**
* @brief Function for getting number of bytes received in the last transaction.
*
* @param[in] p_reg Instance.
*
* @retval Amount of bytes received.
*/
__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
}
__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask)
{
p_reg->SHORTS |= shorts_mask;
}
__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask)
{
p_reg->SHORTS &= ~(shorts_mask);
}
__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENSET = int_mask;
}
__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask)
{
return (bool)(p_reg->INTENSET & int_mask);
}
__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENCLR = int_mask;
}
__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg)
{
uint32_t errsrc_mask = p_reg->ERRORSRC;
p_reg->ERRORSRC = errsrc_mask;
return errsrc_mask;
}
__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg)
{
p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled;
}
__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg)
{
p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled;
}
__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd)
{
p_reg->PSEL.TXD = pseltxd;
p_reg->PSEL.RXD = pselrxd;
}
__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg)
{
nrf_uarte_txrx_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED);
}
__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg)
{
return p_reg->PSEL.TXD;
}
__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg)
{
return p_reg->PSEL.RXD;
}
__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg)
{
return p_reg->PSEL.RTS;
}
__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg)
{
return p_reg->PSEL.CTS;
}
__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, uint32_t pselrts, uint32_t pselcts)
{
p_reg->PSEL.RTS = pselrts;
p_reg->PSEL.CTS = pselcts;
}
__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg)
{
nrf_uarte_hwfc_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED);
}
__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task)
{
return (uint32_t)p_reg + (uint32_t)task;
}
__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg,
nrf_uarte_parity_t parity,
nrf_uarte_hwfc_t hwfc)
{
p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc;
}
__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate)
{
p_reg->BAUDRATE = baudrate;
}
__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg,
uint8_t const * p_buffer,
uint8_t length)
{
p_reg->TXD.PTR = (uint32_t)p_buffer;
p_reg->TXD.MAXCNT = length;
}
__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg)
{
return p_reg->TXD.AMOUNT;
}
__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg,
uint8_t * p_buffer,
uint8_t length)
{
p_reg->RXD.PTR = (uint32_t)p_buffer;
p_reg->RXD.MAXCNT = length;
}
__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg)
{
return p_reg->RXD.AMOUNT;
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#endif //NRF_UARTE_H__

View File

@ -0,0 +1,299 @@
/* 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.
*
*/
/**
* @defgroup nrf_wdt_hal WDT HAL
* @{
* @ingroup nrf_wdt
*
* @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral.
*/
#ifndef NRF_WDT_H__
#define NRF_WDT_H__
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#define NRF_WDT_CHANNEL_NUMBER 0x8UL
#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/
#define NRF_WDT_TASK_SET 1UL
#define NRF_WDT_EVENT_CLEAR 0UL
/**
* @enum nrf_wdt_task_t
* @brief WDT tasks.
*/
typedef enum
{
/*lint -save -e30 -esym(628,__INTADDR__)*/
NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
/*lint -restore*/
} nrf_wdt_task_t;
/**
* @enum nrf_wdt_event_t
* @brief WDT events.
*/
typedef enum
{
/*lint -save -e30*/
NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
/*lint -restore*/
} nrf_wdt_event_t;
/**
* @enum nrf_wdt_behaviour_t
* @brief WDT behavior in CPU SLEEP or HALT mode.
*/
typedef enum
{
NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */
NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */
NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
} nrf_wdt_behaviour_t;
/**
* @enum nrf_wdt_rr_register_t
* @brief WDT reload request registers.
*/
typedef enum
{
NRF_WDT_RR0 = 0, /**< Reload request register 0. */
NRF_WDT_RR1, /**< Reload request register 1. */
NRF_WDT_RR2, /**< Reload request register 2. */
NRF_WDT_RR3, /**< Reload request register 3. */
NRF_WDT_RR4, /**< Reload request register 4. */
NRF_WDT_RR5, /**< Reload request register 5. */
NRF_WDT_RR6, /**< Reload request register 6. */
NRF_WDT_RR7 /**< Reload request register 7. */
} nrf_wdt_rr_register_t;
/**
* @enum nrf_wdt_int_mask_t
* @brief WDT interrupts.
*/
typedef enum
{
NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
} nrf_wdt_int_mask_t;
/**
* @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
*
* @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
*/
__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
{
NRF_WDT->CONFIG = behaviour;
}
/**
* @brief Function for starting the watchdog.
*
* @param[in] task Task.
*/
__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
{
*((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
}
/**
* @brief Function for clearing the WDT event.
*
* @param[in] event Event.
*/
__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
{
*((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
}
/**
* @brief Function for retrieving the state of the WDT event.
*
* @param[in] event Event.
*
* @retval true If the event is set.
* @retval false If the event is not set.
*/
__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
{
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
}
/**
* @brief Function for enabling a specific interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
{
NRF_WDT->INTENSET = int_mask;
}
/**
* @brief Function for retrieving the state of given interrupt.
*
* @param[in] int_mask Interrupt.
*
* @retval true Interrupt is enabled.
* @retval false Interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
{
return (bool)(NRF_WDT->INTENSET & int_mask);
}
/**
* @brief Function for disabling a specific interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
{
NRF_WDT->INTENCLR = int_mask;
}
/**
* @brief Function for returning the address of a specific WDT task register.
*
* @param[in] task Task.
*/
__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
{
return ((uint32_t)NRF_WDT + task);
}
/**
* @brief Function for returning the address of a specific WDT event register.
*
* @param[in] event Event.
*
* @retval address of requested event register
*/
__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
{
return ((uint32_t)NRF_WDT + event);
}
/**
* @brief Function for retrieving the watchdog status.
*
* @retval true If the watchdog is started.
* @retval false If the watchdog is not started.
*/
__STATIC_INLINE bool nrf_wdt_started(void)
{
return (bool)(NRF_WDT->RUNSTATUS);
}
/**
* @brief Function for retrieving the watchdog reload request status.
*
* @param[in] rr_register Reload request register to check.
*
* @retval true If a reload request is running.
* @retval false If no reload request is running.
*/
__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
{
return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
}
/**
* @brief Function for setting the watchdog reload value.
*
* @param[in] reload_value Watchdog counter initial value.
*/
__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
{
NRF_WDT->CRV = reload_value;
}
/**
* @brief Function for retrieving the watchdog reload value.
*
* @retval Reload value.
*/
__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
{
return (uint32_t)NRF_WDT->CRV;
}
/**
* @brief Function for enabling a specific reload request register.
*
* @param[in] rr_register Reload request register to enable.
*/
__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
{
NRF_WDT->RREN |= 0x1UL << rr_register;
}
/**
* @brief Function for disabling a specific reload request register.
*
* @param[in] rr_register Reload request register to disable.
*/
__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
{
NRF_WDT->RREN &= ~(0x1UL << rr_register);
}
/**
* @brief Function for retrieving the status of a specific reload request register.
*
* @param[in] rr_register Reload request register to check.
*
* @retval true If the reload request register is enabled.
* @retval false If the reload request register is not enabled.
*/
__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
{
return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
}
/**
* @brief Function for setting a specific reload request register.
*
* @param[in] rr_register Reload request register to set.
*/
__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
{
NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
}
#endif
/** @} */