Initial commit

This commit is contained in:
2026-04-24 10:52:47 +09:00
commit 1707dc6349
1423 changed files with 1161776 additions and 0 deletions
+385
View File
@@ -0,0 +1,385 @@
/**
* Copyright (c) 2019 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_AAR_H__
#define NRF_AAR_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_aar_hal AAR HAL
* @{
* @ingroup nrf_aar
* @brief Hardware access layer for managing the Accelerated Address Resolver (AAR) peripheral.
*/
/** @brief AAR events. */
typedef enum
{
NRF_AAR_EVENT_END = offsetof(NRF_AAR_Type, EVENTS_END), ///< Address resolution procedure complete.
NRF_AAR_EVENT_RESOLVED = offsetof(NRF_AAR_Type, EVENTS_RESOLVED), ///< Address resolved.
NRF_AAR_EVENT_NOTRESOLVED = offsetof(NRF_AAR_Type, EVENTS_NOTRESOLVED), ///< Address not resolved.
} nrf_aar_event_t;
/** @brief AAR interrupts. */
typedef enum
{
NRF_AAR_INT_END_MASK = AAR_INTENSET_END_Msk, ///< Interrupt on END event.
NRF_AAR_INT_RESOLVED_MASK = AAR_INTENSET_RESOLVED_Msk, ///< Interrupt on RESOLVED event.
NRF_AAR_INT_NOTRESOLVED_MASK = AAR_INTENSET_NOTRESOLVED_Msk, ///< Interrupt on NOTRESOLVED event.
} nrf_aar_int_mask_t;
/** @brief AAR tasks. */
typedef enum
{
NRF_AAR_TASK_START = offsetof(NRF_AAR_Type, TASKS_START), ///< Start address resolution procedure.
NRF_AAR_TASK_STOP = offsetof(NRF_AAR_Type, TASKS_STOP), ///< Stop address resolution procedure.
} nrf_aar_task_t;
/**
* @brief Function for retrieving the state of the AAR event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true Event is set.
* @retval false Event is not set.
*/
__STATIC_INLINE bool nrf_aar_event_check(NRF_AAR_Type const * p_reg,
nrf_aar_event_t event);
/**
* @brief Function for clearing the specified AAR event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be cleared.
*/
__STATIC_INLINE void nrf_aar_event_clear(NRF_AAR_Type * p_reg,
nrf_aar_event_t event);
/**
* @brief Function for getting the address of the specified AAR event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to get the address of.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_aar_event_address_get(NRF_AAR_Type const * p_reg,
nrf_aar_event_t event);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_aar_int_enable(NRF_AAR_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of the specified interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of the interrupt to be checked.
*
* @retval true Interrupt is enabled.
* @retval false Interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_aar_int_enable_check(NRF_AAR_Type const * p_reg,
nrf_aar_int_mask_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_aar_int_disable(NRF_AAR_Type * p_reg, uint32_t mask);
/**
* @brief Function for starting an AAR task.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param task Task to be activated.
*/
__STATIC_INLINE void nrf_aar_task_trigger(NRF_AAR_Type * p_reg, nrf_aar_task_t task);
/**
* @brief Function for getting the address of a specific AAR task register.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param task Requested AAR task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_aar_task_address_get(NRF_AAR_Type const * p_reg,
nrf_aar_task_t task);
/**
* @brief Function for enabling AAR.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_aar_enable(NRF_AAR_Type * p_reg);
/**
* @brief Function for disabling AAR.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_aar_disable(NRF_AAR_Type * p_reg);
/**
* @brief Function for setting the pointer to the Identity Resolving Keys (IRK) data structure.
*
* The size of the provided data structure must correspond to the number of keys available.
* Each key occupies 16 bytes.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param irk_ptr Pointer to the IRK data structure. Must point to the Data RAM region.
*
* @sa nrf_aar_irk_number_set
*/
__STATIC_INLINE void nrf_aar_irk_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * irk_ptr);
/**
* @brief Function for getting the pointer to the Identity Resolving Keys
* data structure.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pointer to the IRK data structure.
*/
__STATIC_INLINE uint8_t const * nrf_aar_irk_pointer_get(NRF_AAR_Type const * p_reg);
/**
* @brief Function for setting the number of keys available in the Identity Resolving Keys
* data structure.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param irk_num Number of keys available in the IRK data structure. Maximum is 16.
* Must correspond to the size of the provided IRK data structure.
*
* @sa nrf_aar_irk_pointer_set
*/
__STATIC_INLINE void nrf_aar_irk_number_set(NRF_AAR_Type * p_reg, uint8_t irk_num);
/**
* @brief Function for getting the number of keys available in the Identity Resolving Keys
* data structure.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Number of keys in the IRK data structure.
*/
__STATIC_INLINE uint8_t nrf_aar_irk_number_get(NRF_AAR_Type const * p_reg);
/**
* @brief Function for setting the pointer to the resolvable address.
*
* The resolvable address must consist of 6 bytes.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param addr_ptr Pointer to the address to resolve using the available IRK keys.
* Must point to the Data RAM region.
*/
__STATIC_INLINE void nrf_aar_addr_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * addr_ptr);
/**
* @brief Function for getting the pointer to the resolvable address.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pointer to the address to resolve.
*/
__STATIC_INLINE uint8_t const * nrf_aar_addr_pointer_get(NRF_AAR_Type const * p_reg);
/**
* @brief Function for setting the pointer to the scratch data area.
*
* The scratch data area is used for temporary storage during the address resolution procedure.
* A space of minimum 3 bytes must be reserved for the scratch data area.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param scratch_ptr Pointer to the scratch data area. Must point to the Data RAM region.
*/
__STATIC_INLINE void nrf_aar_scratch_pointer_set(NRF_AAR_Type * p_reg, uint8_t * scratch_ptr);
/**
* @brief Function for getting the pointer to the scratch data area.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pointer to the scratch data area.
*/
__STATIC_INLINE uint8_t * nrf_aar_scratch_pointer_get(NRF_AAR_Type const * p_reg);
/**
* @brief Function for getting the index of the Identity Resolving Key that was used
* the last time an address was resolved.
*
* This function can be used to get the IRK index that matched the resolvable address,
* provided that @ref NRF_AAR_EVENT_RESOLVED occured. Otherwise, it will return
* the index of the last IRK stored in the IRK data structure.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return The index of the IRK that was used the last time an address was resolved.
*/
__STATIC_INLINE uint8_t nrf_aar_resolution_status_get(NRF_AAR_Type const * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE bool nrf_aar_event_check(NRF_AAR_Type const * p_reg,
nrf_aar_event_t aar_event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)aar_event);
}
__STATIC_INLINE void nrf_aar_event_clear(NRF_AAR_Type * p_reg,
nrf_aar_event_t aar_event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)aar_event)) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)aar_event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_aar_event_address_get(NRF_AAR_Type const * p_reg,
nrf_aar_event_t aar_event)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)aar_event);
}
__STATIC_INLINE void nrf_aar_int_enable(NRF_AAR_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE bool nrf_aar_int_enable_check(NRF_AAR_Type const * p_reg,
nrf_aar_int_mask_t mask)
{
return (bool)(p_reg->INTENSET & mask);
}
__STATIC_INLINE void nrf_aar_int_disable(NRF_AAR_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE void nrf_aar_task_trigger(NRF_AAR_Type * p_reg, nrf_aar_task_t task)
{
*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task) = 1;
}
__STATIC_INLINE uint32_t nrf_aar_task_address_get(NRF_AAR_Type const * p_reg,
nrf_aar_task_t task)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_aar_enable(NRF_AAR_Type * p_reg)
{
p_reg->ENABLE = AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos;
}
__STATIC_INLINE void nrf_aar_disable(NRF_AAR_Type * p_reg)
{
p_reg->ENABLE = AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos;
}
__STATIC_INLINE void nrf_aar_irk_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * irk_ptr)
{
p_reg->IRKPTR = (uint32_t)irk_ptr;
}
__STATIC_INLINE uint8_t const * nrf_aar_irk_pointer_get(NRF_AAR_Type const * p_reg)
{
return (uint8_t const *)(p_reg->IRKPTR);
}
__STATIC_INLINE void nrf_aar_irk_number_set(NRF_AAR_Type * p_reg, uint8_t irk_num)
{
p_reg->NIRK = irk_num;
}
__STATIC_INLINE uint8_t nrf_aar_irk_number_get(NRF_AAR_Type const * p_reg)
{
return (uint8_t)(p_reg->NIRK);
}
__STATIC_INLINE void nrf_aar_addr_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * addr_ptr)
{
p_reg->ADDRPTR = (uint32_t)addr_ptr;
}
__STATIC_INLINE uint8_t const * nrf_aar_addr_pointer_get(NRF_AAR_Type const * p_reg)
{
return (uint8_t const *)(p_reg->ADDRPTR);
}
__STATIC_INLINE void nrf_aar_scratch_pointer_set(NRF_AAR_Type * p_reg, uint8_t * scratch_ptr)
{
p_reg->SCRATCHPTR = (uint32_t)scratch_ptr;
}
__STATIC_INLINE uint8_t * nrf_aar_scratch_pointer_get(NRF_AAR_Type const * p_reg)
{
return (uint8_t *)(p_reg->SCRATCHPTR);
}
__STATIC_INLINE uint8_t nrf_aar_resolution_status_get(NRF_AAR_Type const * p_reg)
{
return (uint8_t)(p_reg->STATUS);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_AAR_H__
+155
View File
@@ -0,0 +1,155 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_ACL_H__
#define NRF_ACL_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_ACL_REGION_SIZE_MAX (512 * 1024UL)
/**
* @defgroup nrf_acl_hal ACL HAL
* @{
* @ingroup nrf_acl
* @brief Hardware access layer for managing the Access Control List (ACL) peripheral.
*/
/** @brief ACL permissions. */
typedef enum
{
NRF_ACL_PERM_READ_NO_WRITE = ACL_ACL_PERM_WRITE_Msk, /**< Read allowed, write disallowed. */
NRF_ACL_PERM_NO_READ_WRITE = ACL_ACL_PERM_READ_Msk, /**< Read disallowed, write allowed. */
NRF_ACL_PERM_NO_READ_NO_WRITE = ACL_ACL_PERM_READ_Msk | ACL_ACL_PERM_WRITE_Msk /**< Read disallowed, write disallowed. */
} nrf_acl_perm_t;
/**
* @brief Function for setting region parameters for given ACL region.
*
* Address must be word and page aligned. Size must be page aligned.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id ACL region index.
* @param[in] address Start address.
* @param[in] size Size of region to protect in bytes.
* @param[in] perm Permissions to set for region to protect.
*/
__STATIC_INLINE void nrf_acl_region_set(NRF_ACL_Type * p_reg,
uint32_t region_id,
uint32_t address,
size_t size,
nrf_acl_perm_t perm);
/**
* @brief Function for getting the configured region address of a specific ACL region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id ACL region index.
*
* @return Configured region address of given ACL region.
*/
__STATIC_INLINE uint32_t nrf_acl_region_address_get(NRF_ACL_Type * p_reg, uint32_t region_id);
/**
* @brief Function for getting the configured region size of a specific ACL region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id ACL region index.
*
* @return Configured region size of given ACL region.
*/
__STATIC_INLINE size_t nrf_acl_region_size_get(NRF_ACL_Type * p_reg, uint32_t region_id);
/**
* @brief Function for getting the configured region permissions of a specific ACL region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id ACL region index.
*
* @return Configured region permissions of given ACL region.
*/
__STATIC_INLINE nrf_acl_perm_t nrf_acl_region_perm_get(NRF_ACL_Type * p_reg, uint32_t region_id);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_acl_region_set(NRF_ACL_Type * p_reg,
uint32_t region_id,
uint32_t address,
size_t size,
nrf_acl_perm_t perm)
{
NRFX_ASSERT(region_id < ACL_REGIONS_COUNT);
NRFX_ASSERT(address % NRF_FICR->CODEPAGESIZE == 0);
NRFX_ASSERT(size <= NRF_ACL_REGION_SIZE_MAX);
NRFX_ASSERT(size != 0);
p_reg->ACL[region_id].ADDR = address;
p_reg->ACL[region_id].SIZE = size;
p_reg->ACL[region_id].PERM = perm;
}
__STATIC_INLINE uint32_t nrf_acl_region_address_get(NRF_ACL_Type * p_reg, uint32_t region_id)
{
return (uint32_t)p_reg->ACL[region_id].ADDR;
}
__STATIC_INLINE size_t nrf_acl_region_size_get(NRF_ACL_Type * p_reg, uint32_t region_id)
{
return (size_t)p_reg->ACL[region_id].SIZE;
}
__STATIC_INLINE nrf_acl_perm_t nrf_acl_region_perm_get(NRF_ACL_Type * p_reg, uint32_t region_id)
{
return (nrf_acl_perm_t)p_reg->ACL[region_id].PERM;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_ACL_H__
+134
View File
@@ -0,0 +1,134 @@
/**
* Copyright (c) 2019 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_BPROT_H__
#define NRF_BPROT_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_bprot_hal BPROT HAL
* @{
* @ingroup nrf_bprot
* @brief Hardware access layer for managing the Block Protection (BPROT) mechanism.
*/
/**
* @brief Function for enabling protection for specified non-volatile memory blocks.
*
* Blocks are arranged into groups of 32 blocks each. Each block size is 4 kB.
* Any attempt to write or erase a protected block will result in hard fault.
* The memory block protection can be disabled only by resetting the device.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] group_idx Non-volatile memory group containing memory blocks to protect.
* @param[in] block_mask Non-volatile memory blocks to protect. Each bit in bitmask represents
* one memory block in the specified group.
*/
__STATIC_INLINE void nrf_bprot_nvm_blocks_protection_enable(NRF_BPROT_Type * p_reg,
uint8_t group_idx,
uint32_t block_mask);
/**
* @brief Function for setting the non-volatile memory (NVM) protection during debug.
*
* NVM protection is disabled by default while debugging.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if NVM protection during debug is to be enabled.
* False if otherwise.
*/
__STATIC_INLINE void nrf_bprot_nvm_protection_in_debug_set(NRF_BPROT_Type * p_reg,
bool enable);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_bprot_nvm_blocks_protection_enable(NRF_BPROT_Type * p_reg,
uint8_t group_idx,
uint32_t block_mask)
{
switch (group_idx)
{
case 0:
p_reg->CONFIG0 = block_mask;
break;
case 1:
p_reg->CONFIG1 = block_mask;
break;
#if defined(BPROT_CONFIG2_REGION64_Pos)
case 2:
p_reg->CONFIG2 = block_mask;
break;
#endif
#if defined(BPROT_CONFIG3_REGION96_Pos)
case 3:
p_reg->CONFIG3 = block_mask;
break;
#endif
default:
NRFX_ASSERT(false);
break;
}
}
__STATIC_INLINE void nrf_bprot_nvm_protection_in_debug_set(NRF_BPROT_Type * p_reg,
bool enable)
{
p_reg->DISABLEINDEBUG =
(enable ? 0 : BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Msk);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_BPROT_H__
+488
View File
@@ -0,0 +1,488 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_CCM_H__
#define NRF_CCM_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_ccm_hal AES CCM HAL
* @{
* @ingroup nrf_ccm
* @brief Hardware access layer for managing the AES CCM peripheral.
*/
/** @brief CCM tasks. */
typedef enum
{
NRF_CCM_TASK_KSGEN = offsetof(NRF_CCM_Type, TASKS_KSGEN), ///< Start generation of key-stream.
NRF_CCM_TASK_CRYPT = offsetof(NRF_CCM_Type, TASKS_CRYPT), ///< Start encryption/decryption.
NRF_CCM_TASK_STOP = offsetof(NRF_CCM_Type, TASKS_STOP), ///< Stop encryption/decryption.
#if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
NRF_CCM_TASK_RATEOVERRIDE = offsetof(NRF_CCM_Type, TASKS_RATEOVERRIDE), ///< Override DATARATE setting in MODE register.
#endif
} nrf_ccm_task_t;
/** @brief CCM events. */
typedef enum
{
NRF_CCM_EVENT_ENDKSGEN = offsetof(NRF_CCM_Type, EVENTS_ENDKSGEN), ///< Keystream generation complete.
NRF_CCM_EVENT_ENDCRYPT = offsetof(NRF_CCM_Type, EVENTS_ENDCRYPT), ///< Encrypt/decrypt complete.
NRF_CCM_EVENT_ERROR = offsetof(NRF_CCM_Type, EVENTS_ERROR), ///< CCM error event.
} nrf_ccm_event_t;
/** @brief CCM interrupts. */
typedef enum
{
NRF_CCM_INT_ENDKSGEN_MASK = CCM_INTENSET_ENDKSGEN_Msk, ///< Interrupt on ENDKSGEN event.
NRF_CCM_INT_ENDCRYPT_MASK = CCM_INTENSET_ENDCRYPT_Msk, ///< Interrupt on ENDCRYPT event.
NRF_CCM_INT_ERROR_MASK = CCM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event.
} nrf_ccm_int_mask_t;
/** @brief CCM modes of operation. */
typedef enum
{
NRF_CCM_MODE_ENCRYPTION = CCM_MODE_MODE_Encryption, ///< Encryption mode.
NRF_CCM_MODE_DECRYPTION = CCM_MODE_MODE_Decryption, ///< Decryption mode.
} nrf_ccm_mode_t;
#if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
/** @brief CCM data rates. */
typedef enum
{
NRF_CCM_DATARATE_1M = CCM_MODE_DATARATE_1Mbit, ///< 1 Mbps.
NRF_CCM_DATARATE_2M = CCM_MODE_DATARATE_2Mbit, ///< 2 Mbps.
#if defined(CCM_MODE_DATARATE_125Kbps) || defined(__NRFX_DOXYGEN__)
NRF_CCM_DATARATE_125K = CCM_MODE_DATARATE_125Kbps, ///< 125 Kbps.
#endif
#if defined(CCM_MODE_DATARATE_500Kbps) || defined(__NRFX_DOXYGEN__)
NRF_CCM_DATARATE_500K = CCM_MODE_DATARATE_500Kbps, ///< 500 Kbps.
#endif
} nrf_ccm_datarate_t;
#endif // defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
#if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
/** @brief CCM packet length options. */
typedef enum
{
NRF_CCM_LENGTH_DEFAULT = CCM_MODE_LENGTH_Default, ///< Default length.
NRF_CCM_LENGTH_EXTENDED = CCM_MODE_LENGTH_Extended, ///< Extended length.
} nrf_ccm_length_t;
#endif // defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
/** @brief CCM configuration. */
typedef struct {
nrf_ccm_mode_t mode; ///< Operation mode.
#if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
nrf_ccm_datarate_t datarate; ///< Data rate.
#endif
#if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
nrf_ccm_length_t length; ///< Lenght of the CCM packet.
#endif
} nrf_ccm_config_t;
/**
* @brief Function for activating a specific CCM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
nrf_ccm_task_t task);
/**
* @brief Function for getting the address of a specific CCM task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
nrf_ccm_task_t task);
/**
* @brief Function for clearing a specific CCM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type * p_reg,
nrf_ccm_event_t event);
/**
* @brief Function for retrieving the state of a specific CCM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
nrf_ccm_event_t event);
/**
* @brief Function for getting the address of a specific CCM event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
nrf_ccm_event_t event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ccm_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
nrf_ccm_int_mask_t ccm_int);
/**
* @brief Function for enabling the CCM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg);
/**
* @brief Function for disabling the CCM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg);
/**
* @brief Function for setting the CCM peripheral configuration.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] p_config Pointer to the structure with configuration to be set.
*/
__STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type * p_reg,
nrf_ccm_config_t const * p_config);
#if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the length of key-stream generated
* when the packet length is configured as extended.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] size Maximum length of the key-stream.
*/
__STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
uint8_t size);
#endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the MIC check result.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true The MIC check passed.
* @retval false The MIC check failed.
*/
__STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg);
/**
* @brief Function for setting the pointer to the data structure
* holding the AES key and the CCM NONCE vector.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] p_data Pointer to the data structure.
*/
__STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data);
/**
* @brief Function for getting the pointer to the data structure
* holding the AES key and the CCM NONCE vector.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pointer to the data structure.
*/
__STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg);
/**
* @brief Function for setting the input data pointer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] p_data Input data pointer.
*/
__STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data);
/**
* @brief Function for getting the input data pointer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Input data pointer.
*/
__STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg);
/**
* @brief Function for setting the output data pointer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] p_data Output data pointer.
*/
__STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data);
/**
* @brief Function for getting the output data pointer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Output data pointer.
*/
__STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg);
/**
* @brief Function for setting the pointer to the scratch area used for
* temporary storage.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] p_area Pointer to the scratch area.
*/
__STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_area);
/**
* @brief Function for getting the pointer to the scratch area.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pointer to the scratch area.
*/
__STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg);
#if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the data rate override value.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] datarate Override value to be applied when the RATEOVERRIDE task
* is triggered.
*/
__STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,
nrf_ccm_datarate_t datarate);
#endif // defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
nrf_ccm_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
nrf_ccm_task_t task)
{
return ((uint32_t)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type * p_reg,
nrf_ccm_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
nrf_ccm_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
nrf_ccm_event_t event)
{
return ((uint32_t)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
nrf_ccm_int_mask_t ccm_int)
{
return (bool)(p_reg->INTENSET & ccm_int);
}
__STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg)
{
p_reg->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg)
{
p_reg->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type * p_reg,
nrf_ccm_config_t const * p_config)
{
p_reg->MODE = (((uint32_t)p_config->mode << CCM_MODE_MODE_Pos) |
#if defined(CCM_MODE_DATARATE_Pos)
((uint32_t)p_config->datarate << CCM_MODE_DATARATE_Pos) |
#endif
#if defined(CCM_MODE_LENGTH_Pos)
((uint32_t)p_config->length << CCM_MODE_LENGTH_Pos) |
#endif
0);
}
#if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
__STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
uint8_t size)
{
NRFX_ASSERT((size >= 0x1B) && (size <= 0xFB));
p_reg->MAXPACKETSIZE = size;
}
#endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
__STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg)
{
return (bool)(p_reg->MICSTATUS);
}
__STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data)
{
p_reg->CNFPTR = (uint32_t)p_data;
}
__STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)
{
return (uint32_t *)(p_reg->CNFPTR);
}
__STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data)
{
p_reg->INPTR = (uint32_t)p_data;
}
__STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)
{
return (uint32_t *)(p_reg->INPTR);
}
__STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_data)
{
p_reg->OUTPTR = (uint32_t)p_data;
}
__STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)
{
return (uint32_t *)(p_reg->OUTPTR);
}
__STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,
uint32_t const * p_area)
{
p_reg->SCRATCHPTR = (uint32_t)p_area;
}
__STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)
{
return (uint32_t *)(p_reg->SCRATCHPTR);
}
#if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos)
__STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,
nrf_ccm_datarate_t datarate)
{
p_reg->RATEOVERRIDE = ((uint32_t)datarate << CCM_RATEOVERRIDE_RATEOVERRIDE_Pos);
}
#endif
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_CCM_H__
+530
View File
@@ -0,0 +1,530 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_CLOCK_H__
#define NRF_CLOCK_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_clock_hal Clock HAL
* @{
* @ingroup nrf_clock
* @brief Hardware access layer for managing the CLOCK peripheral.
*
* This code can be used to managing low-frequency clock (LFCLK) and the high-frequency clock
* (HFCLK) settings.
*/
#if defined(CLOCK_LFCLKSRC_BYPASS_Msk) && defined(CLOCK_LFCLKSRC_EXTERNAL_Msk)
// Enable support for external LFCLK sources. Read more in the Product Specification.
#define NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES
#endif
#if defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Presence of the Low Frequency Clock calibration.
*
* In some MCUs there is possibility to use LFCLK calibration.
*/
#define NRF_CLOCK_HAS_CALIBRATION 1
#else
#define NRF_CLOCK_HAS_CALIBRATION 0
#endif // defined(CLOCK_CTIV_CTIV_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Low-frequency clock sources.
* @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers.
*/
typedef enum
{
#if defined(CLOCK_LFCLKSRC_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */
#else
NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_LFRC, /**< Internal 32 kHz RC oscillator. */
#endif
#if defined(CLOCK_LFCLKSRC_SRC_Xtal) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */
#else
NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_LFXO, /**< External 32 kHz crystal. */
#endif
#if defined(CLOCK_LFCLKSRC_SRC_Synth) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth, /**< Internal 32 kHz synthesizer from HFCLK system clock. */
#endif
#if defined(NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES) || defined(__NRFX_DOXYGEN__)
/**
* External 32 kHz low swing signal. Used only with the LFCLKSRC register.
* For the others @ref NRF_CLOCK_LFCLK_Xtal is returned for this setting.
*/
NRF_CLOCK_LFCLK_Xtal_Low_Swing = (CLOCK_LFCLKSRC_SRC_Xtal |
(CLOCK_LFCLKSRC_EXTERNAL_Enabled << CLOCK_LFCLKSRC_EXTERNAL_Pos)),
/**
* External 32 kHz full swing signal. Used only with the LFCLKSRC register.
* For the others @ref NRF_CLOCK_LFCLK_Xtal is returned for this setting.
*/
NRF_CLOCK_LFCLK_Xtal_Full_Swing = (CLOCK_LFCLKSRC_SRC_Xtal |
(CLOCK_LFCLKSRC_BYPASS_Enabled << CLOCK_LFCLKSRC_BYPASS_Pos) |
(CLOCK_LFCLKSRC_EXTERNAL_Enabled << CLOCK_LFCLKSRC_EXTERNAL_Pos)),
#endif // defined(NRF_CLOCK_USE_EXTERNAL_LFCLK_SOURCES) || defined(__NRFX_DOXYGEN__)
} nrf_clock_lfclk_t;
/** @brief High-frequency clock sources. */
typedef enum
{
#if defined(CLOCK_HFCLKSTAT_SRC_RC) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */
#endif
#if defined(CLOCK_HFCLKSTAT_SRC_Xtal) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */
#else
NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_HFXO /**< External 32 MHz crystal oscillator. */
#endif
} 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 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. */
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
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. */
#endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_INT_CTSTARTED_MASK = CLOCK_INTENSET_CTSTARTED_Msk, /**< Interrupt on CTSTARTED event. */
NRF_CLOCK_INT_CTSTOPPED_MASK = CLOCK_INTENSET_CTSTOPPED_Msk /**< Interrupt on CTSTOPPED event. */
#endif
} 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
{
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.*/
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
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.*/
#endif
} nrf_clock_task_t;
/** @brief Events. */
typedef enum
{
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.*/
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
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.*/
#endif
#if defined(CLOCK_INTENSET_CTSTARTED_Msk) || defined(__NRFX_DOXYGEN__)
NRF_CLOCK_EVENT_CTSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTARTED), /**< Calibration timer started.*/
NRF_CLOCK_EVENT_CTSTOPPED = offsetof(NRF_CLOCK_Type, EVENTS_CTSTOPPED) /**< Calibration timer stopped.*/
#endif
} nrf_clock_event_t;
/**
* @brief Function for enabling the specified interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask);
/**
* @brief Function for disabling the specified interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask);
/**
* @brief Function for retrieving the state of the specified interrupt.
*
* @param[in] int_mask Interrupt.
*
* @retval true The interrupt is enabled.
* @retval false 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 the specified task.
* @details This function can be used by the PPI module.
*
* @param[in] task CLOCK 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 the specified task.
*
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task);
/**
* @brief Function for retrieving the address of the specified event.
* @details This function can be used by the PPI module.
*
* @param[in] event CLOCK Event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event);
/**
* @brief Function for clearing the specified event.
*
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event);
/**
* @brief Function for retrieving the state of the specified event.
*
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__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 The internal 32 kHz RC oscillator
* is the selected source for the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Xtal An external 32 kHz crystal oscillator
* is the selected source for the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Synth 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 The internal 32 kHz RC oscillator
* is the active source of the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Xtal An external 32 kHz crystal oscillator
* is the active source of the low-frequency clock.
* @retval NRF_CLOCK_LFCLK_Synth 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 The internal 32 kHz RC oscillator
* is running and generating the LFCLK clock.
* @retval NRF_CLOCK_LFCLK_Xtal An external 32 kHz crystal oscillator
* is running and generating the LFCLK clock.
* @retval NRF_CLOCK_LFCLK_Synth 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 The LFCLK clock is not running.
* @retval true 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 The task LFCLKSTART has not been triggered.
* @retval NRF_CLOCK_START_TASK_TRIGGERED 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 The internal RC oscillator is the active
* source of the high-frequency clock.
* @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY An external 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 The HFCLK clock is not running.
* @retval true 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 The task HFCLKSTART has not been triggered.
* @retval NRF_CLOCK_START_TASK_TRIGGERED The task HFCLKSTART has been triggered.
*/
__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void);
#if (NRF_CLOCK_HAS_CALIBRATION) || defined(__NRFX_DOXYGEN__)
/**
* @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);
#endif
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* CLOCK task.
*
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_clock_subscribe_set(nrf_clock_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* CLOCK task.
*
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_clock_subscribe_clear(nrf_clock_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* CLOCK event.
*
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_clock_publish_set(nrf_clock_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* CLOCK event.
*
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_clock_publish_clear(nrf_clock_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
#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)) = 0x1UL;
}
__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)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + (uint32_t)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);
}
__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void)
{
return (nrf_clock_lfclk_t)(NRF_CLOCK->LFCLKSRC);
}
__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);
}
#if (NRF_CLOCK_HAS_CALIBRATION)
__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
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_clock_subscribe_set(nrf_clock_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_CLOCK + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | CLOCK_SUBSCRIBE_HFCLKSTART_EN_Msk);
}
__STATIC_INLINE void nrf_clock_subscribe_clear(nrf_clock_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_CLOCK + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_clock_publish_set(nrf_clock_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_CLOCK + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | CLOCK_PUBLISH_HFCLKSTARTED_EN_Msk);
}
__STATIC_INLINE void nrf_clock_publish_clear(nrf_clock_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) NRF_CLOCK + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_CLOCK_H__
+91
View File
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2012 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <nrfx.h>
#include "nrf_ecb.h"
#include <string.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);
}
+287
View File
@@ -0,0 +1,287 @@
/**
* Copyright (c) 2012 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_ECB_H__
#define NRF_ECB_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_ecb_drv AES ECB encryption driver
* @{
* @ingroup nrf_ecb
* @brief Driver for the Advanced Encryption Standard (AES) Electronic Code Book (ECB) peripheral.
*
* To encrypt 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.
*/
/**
* @brief Function for initializing and powering on the ECB peripheral.
*
* This function allocates memory for the ECBDATAPTR.
*
* @retval true The initialization was successful.
* @retval false The power-on failed.
*/
bool nrf_ecb_init(void);
/**
* @brief Function for encrypting 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, 16 bytes will be written.
* @param src Source with 16-byte data to be encrypted.
*
* @retval true The encryption operation completed.
* @retval false 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.
*
* @param key Pointer to the key. 16 bytes will be read.
*/
void nrf_ecb_set_key(const uint8_t * key);
/** @} */
/**
* @defgroup nrf_ecb_hal AES ECB encryption HAL
* @{
* @ingroup nrf_ecb
* @brief Hardware access layer (HAL) for managing the Advanced Encryption Standard (AES) Electronic Codebook (ECB) peripheral.
*/
/** @brief ECB tasks. */
typedef enum
{
NRF_ECB_TASK_STARTECB = offsetof(NRF_ECB_Type, TASKS_STARTECB), /**< Task for starting the ECB block encryption. */
NRF_ECB_TASK_STOPECB = offsetof(NRF_ECB_Type, TASKS_STOPECB), /**< Task for stopping the ECB block encryption. */
} nrf_ecb_task_t;
/** @brief ECB events. */
typedef enum
{
NRF_ECB_EVENT_ENDECB = offsetof(NRF_ECB_Type, EVENTS_ENDECB), /**< ECB block encrypt complete. */
NRF_ECB_EVENT_ERRORECB = offsetof(NRF_ECB_Type, EVENTS_ERRORECB), /**< ECB block encrypt aborted because of a STOPECB task or due to an error. */
} nrf_ecb_event_t;
/** @brief ECB interrupts. */
typedef enum
{
NRF_ECB_INT_ENDECB_MASK = ECB_INTENSET_ENDECB_Msk, ///< Interrupt on ENDECB event.
NRF_ECB_INT_ERRORECB_MASK = ECB_INTENSET_ERRORECB_Msk, ///< Interrupt on ERRORECB event.
} nrf_ecb_int_mask_t;
/**
* @brief Function for activating the specified ECB task.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_ecb_task_trigger(NRF_ECB_Type * p_reg, nrf_ecb_task_t task);
/**
* @brief Function for getting the address of the specified ECB task register.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_ecb_task_address_get(NRF_ECB_Type const * p_reg,
nrf_ecb_task_t task);
/**
* @brief Function for clearing the specified ECB event.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_ecb_event_clear(NRF_ECB_Type * p_reg, nrf_ecb_event_t event);
/**
* @brief Function for retrieving the state of the ECB event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_ecb_event_check(NRF_ECB_Type const * p_reg, nrf_ecb_event_t event);
/**
* @brief Function for getting the address of the specified ECB event register.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_ecb_event_address_get(NRF_ECB_Type const * p_reg,
nrf_ecb_event_t event);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_ecb_int_enable(NRF_ECB_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_ecb_int_disable(NRF_ECB_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] ecb_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_ecb_int_enable_check(NRF_ECB_Type const * p_reg,
nrf_ecb_int_mask_t ecb_int);
/**
* @brief Function for setting the pointer to the ECB data buffer.
*
* @note The buffer has to be placed in the Data RAM region.
* For description of the data structure in this buffer, see the Product Specification.
*
* @param[in] p_reg Pointer to the peripheral register structure.
* @param[in] p_buffer Pointer to the ECB data buffer.
*/
__STATIC_INLINE void nrf_ecb_data_pointer_set(NRF_ECB_Type * p_reg, void const * p_buffer);
/**
* @brief Function for getting the pointer to the ECB data buffer.
*
* @param[in] p_reg Pointer to the peripheral register structure.
*
* @return Pointer to the ECB data buffer.
*/
__STATIC_INLINE void * nrf_ecb_data_pointer_get(NRF_ECB_Type const * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_ecb_task_trigger(NRF_ECB_Type * p_reg, nrf_ecb_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_ecb_task_address_get(NRF_ECB_Type const * p_reg,
nrf_ecb_task_t task)
{
return ((uint32_t)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_ecb_event_clear(NRF_ECB_Type * p_reg, nrf_ecb_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_ecb_event_check(NRF_ECB_Type const * p_reg, nrf_ecb_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_ecb_event_address_get(NRF_ECB_Type const * p_reg,
nrf_ecb_event_t event)
{
return ((uint32_t)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_ecb_int_enable(NRF_ECB_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_ecb_int_disable(NRF_ECB_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_ecb_int_enable_check(NRF_ECB_Type const * p_reg,
nrf_ecb_int_mask_t ecb_int)
{
return (bool)(p_reg->INTENSET & ecb_int);
}
__STATIC_INLINE void nrf_ecb_data_pointer_set(NRF_ECB_Type * p_reg, void const * p_buffer)
{
p_reg->ECBDATAPTR = (uint32_t)p_buffer;
}
__STATIC_INLINE void * nrf_ecb_data_pointer_get(NRF_ECB_Type const * p_reg)
{
return (void *)(p_reg->ECBDATAPTR);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_ECB_H__
+467
View File
@@ -0,0 +1,467 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_EGU_H__
#define NRF_EGU_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_egu_hal EGU HAL
* @{
* @ingroup nrf_swi_egu
* @brief Hardware access layer for managing the Event Generator Unit (EGU) peripheral.
*/
/** @brief EGU tasks. */
typedef enum
{
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. */
} nrf_egu_task_t;
/** @brief EGU events. */
typedef enum
{
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. */
} nrf_egu_event_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 getting the maximum channel number of the given EGU.
*
* @param NRF_EGUx EGU instance.
*
* @return Number of available channels.
*/
__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx);
/**
* @brief Function for triggering the specified 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);
/**
* @brief Function for returning the address of the specified EGU task register.
*
* @param NRF_EGUx EGU instance.
* @param egu_task EGU task.
*
* @return Address of the specified EGU task register.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_task_t egu_task);
/**
* @brief Function for returning the address of the specified EGU TRIGGER task register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @return Address of the specified EGU TRIGGER task register.
*/
__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel);
/**
* @brief Function for returning the specified EGU TRIGGER task.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @return The specified EGU TRIGGER task.
*/
__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel);
/**
* @brief Function for retrieving the state of the UARTE event.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event);
/**
* @brief Function for clearing the specified 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);
/**
* @brief Function for returning the address of the specified EGU event register.
*
* @param NRF_EGUx EGU instance.
* @param egu_event EGU event.
*
* @return Address of the specified EGU event register.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event);
/**
* @brief Function for returning address of the specified EGU TRIGGERED event register.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @return Address of the specified EGU TRIGGERED event register.
*/
__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel);
/**
* @brief Function for returning the specified EGU TRIGGERED event.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @return The specified EGU TRIGGERED event.
*/
__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel);
/**
* @brief Function for enabling one or more of the EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t mask);
/**
* @brief Function for retrieving the state of one or more of the EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param mask Mask of interrupts to be checked.
*
* @retval true All of the specified interrupts are enabled.
* @retval false At least one of the specified interrupts is disabled.
*/
__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t mask);
/**
* @brief Function for disabling one or more of the EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t mask);
/**
* @brief Function for retrieving one or more of the EGU interrupts.
*
* @param NRF_EGUx EGU instance.
* @param channel Channel number.
*
* @return EGU interrupt mask.
*/
__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* EGU task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_egu_subscribe_set(NRF_EGU_Type * p_reg,
nrf_egu_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* EGU task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_egu_subscribe_clear(NRF_EGU_Type * p_reg,
nrf_egu_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* EGU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_egu_publish_set(NRF_EGU_Type * p_reg,
nrf_egu_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* EGU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_egu_publish_clear(NRF_EGU_Type * p_reg,
nrf_egu_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx)
{
if (NRF_EGUx == NRF_EGU0){
return EGU0_CH_NUM;
}
if (NRF_EGUx == NRF_EGU1){
return EGU1_CH_NUM;
}
#if EGU_COUNT > 2
if (NRF_EGUx == NRF_EGU2){
return EGU2_CH_NUM;
}
if (NRF_EGUx == NRF_EGU3){
return EGU3_CH_NUM;
}
if (NRF_EGUx == NRF_EGU4){
return EGU4_CH_NUM;
}
if (NRF_EGUx == NRF_EGU5){
return EGU5_CH_NUM;
}
#endif
return 0;
}
__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task)
{
NRFX_ASSERT(NRF_EGUx);
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_task_t egu_task)
{
NRFX_ASSERT(NRF_EGUx);
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task);
}
__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
NRFX_ASSERT(NRF_EGUx);
NRFX_ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel];
}
__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel)
{
NRFX_ASSERT(NRF_EGUx);
NRFX_ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
NRFX_ASSERT(NRF_EGUx);
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
NRFX_ASSERT(NRF_EGUx);
*((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx,
nrf_egu_event_t egu_event)
{
NRFX_ASSERT(NRF_EGUx);
return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event);
}
__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
NRFX_ASSERT(NRF_EGUx);
NRFX_ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel];
}
__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx,
uint8_t channel)
{
NRFX_ASSERT(NRF_EGUx);
NRFX_ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t)));
}
__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t mask)
{
NRFX_ASSERT(NRF_EGUx);
NRF_EGUx->INTENSET = mask;
}
__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t mask)
{
NRFX_ASSERT(NRF_EGUx);
return (bool)(NRF_EGUx->INTENSET & mask);
}
__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t mask)
{
NRFX_ASSERT(NRF_EGUx);
NRF_EGUx->INTENCLR = mask;
}
__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel)
{
NRFX_ASSERT(NRF_EGUx);
NRFX_ASSERT(channel < nrf_egu_channel_count(NRF_EGUx));
return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel));
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_egu_subscribe_set(NRF_EGU_Type * p_reg,
nrf_egu_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | EGU_SUBSCRIBE_TRIGGER_EN_Msk);
}
__STATIC_INLINE void nrf_egu_subscribe_clear(NRF_EGU_Type * p_reg,
nrf_egu_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_egu_publish_set(NRF_EGU_Type * p_reg,
nrf_egu_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | EGU_PUBLISH_TRIGGERED_EN_Msk);
}
__STATIC_INLINE void nrf_egu_publish_clear(NRF_EGU_Type * p_reg,
nrf_egu_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif
+159
View File
@@ -0,0 +1,159 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_FICR_H__
#define NRF_FICR_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_ficr_hal FICR HAL
* @{
* @ingroup nrf_ficr
* @brief Hardware access layer (HAL) for getting data from
* the Factory Information Configuration Registers (FICR).
*/
/**
* @brief Function for getting the size of the code memory page.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Code memory page size in bytes.
*/
__STATIC_INLINE uint32_t nrf_ficr_codepagesize_get(NRF_FICR_Type const * p_reg);
/**
* @brief Function for getting the size of the code memory rendered as number of pages.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Code memory size rendered as number of pages.
*/
__STATIC_INLINE uint32_t nrf_ficr_codesize_get(NRF_FICR_Type const * p_reg);
/**
* @brief Function for getting the unique device identifier.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] reg_id Register index.
*
* @return Unique device identifier.
*/
__STATIC_INLINE uint32_t nrf_ficr_deviceid_get(NRF_FICR_Type const * p_reg, uint32_t reg_id);
#if defined(FICR_NFC_TAGHEADER0_MFGID_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the default header values for the NFC tag.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] tagheader_id Tag header index.
*
* @return The default header value of the NFC tag for the specified header index.
*/
__STATIC_INLINE uint32_t nrf_ficr_nfc_tagheader_get(NRF_FICR_Type const * p_reg,
uint32_t tagheader_id);
#endif // defined(FICR_NFC_TAGHEADER0_MFGID_Msk) || defined(__NRFX_DOXYGEN__)
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint32_t nrf_ficr_codepagesize_get(NRF_FICR_Type const * p_reg)
{
#if defined(FICR_INFO_CODEPAGESIZE_CODEPAGESIZE_Msk)
return p_reg->INFO.CODEPAGESIZE;
#else
return p_reg->CODEPAGESIZE;
#endif
}
__STATIC_INLINE uint32_t nrf_ficr_codesize_get(NRF_FICR_Type const * p_reg)
{
#if defined(FICR_INFO_CODESIZE_CODESIZE_Msk)
return p_reg->INFO.CODESIZE;
#else
return p_reg->CODESIZE;
#endif
}
__STATIC_INLINE uint32_t nrf_ficr_deviceid_get(NRF_FICR_Type const * p_reg, uint32_t reg_id)
{
#if defined(FICR_INFO_DEVICEID_DEVICEID_Msk)
return p_reg->INFO.DEVICEID[reg_id];
#else
return p_reg->DEVICEID[reg_id];
#endif
}
#if defined(FICR_NFC_TAGHEADER0_MFGID_Msk)
__STATIC_INLINE uint32_t nrf_ficr_nfc_tagheader_get(NRF_FICR_Type const * p_reg,
uint32_t tagheader_id)
{
switch(tagheader_id) {
case 0:
return p_reg->NFC.TAGHEADER0;
break;
case 1:
return p_reg->NFC.TAGHEADER1;
break;
case 2:
return p_reg->NFC.TAGHEADER2;
break;
case 3:
return p_reg->NFC.TAGHEADER3;
break;
default:
return 0;
}
}
#endif // defined(FICR_NFC_TAGHEADER0_MFGID_Msk)
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_FICR_H__
+899
View File
@@ -0,0 +1,899 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_GPIO_H__
#define NRF_GPIO_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NRF_P0
#define NRF_P0 NRF_GPIO
#endif
#if (GPIO_COUNT == 1)
#define NUMBER_OF_PINS (P0_PIN_NUM)
#define GPIO_REG_LIST {NRF_P0}
#elif (GPIO_COUNT == 2)
#define NUMBER_OF_PINS (P0_PIN_NUM + P1_PIN_NUM)
#define GPIO_REG_LIST {NRF_P0, NRF_P1}
#else
#error "Not supported."
#endif
#if defined(NRF52820_XXAA)
#include <nrf_erratas.h>
#endif
/**
* @defgroup nrf_gpio_hal GPIO HAL
* @{
* @ingroup nrf_gpio
* @brief Hardware access layer for managing the GPIO peripheral.
*/
#if defined(GPIO_LATCH_PIN0_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the functionality of latching GPIO state change is present. */
#define NRF_GPIO_LATCH_PRESENT
#endif
/** @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions. */
#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
/** @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 pull-up resistor disabled.
NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pull-down resistor enabled.
NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pull-up 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 output pins 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).
*
* @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.
*
* @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).
*/
__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 input pins with given initial value set, hiding inner details.
* This function can be used to configure pin range as simple input.
*
* @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.
*
* @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).
*/
__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.
* @param dir Pin direction.
* @param input Connect or disconnect the 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, hiding inner details.
* This function can be used to configure a pin as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
*
* @note Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output.
*
* @param pin_number Specifies the pin number.
*/
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
/**
* @brief Function for configuring the given GPIO pin number as input, hiding inner details.
* This function can be used to configure a pin as simple input.
*
* @note Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable.
*
* @param pin_number Specifies the pin number.
* @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high).
*/
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
/**
* @brief Function for resetting pin configuration to its default state.
*
* @param pin_number Specifies the pin number.
*/
__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.
*
*/
__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.
*/
__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number);
/**
* @brief Function for configuring the given GPIO pin number as input, hiding inner details.
* This function can be used to configure pin range as simple input.
* 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.
* @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.
* @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 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.
*
* For this function to have any effect, the pin must be configured as an output.
*
* @param pin_number Specifies the pin number to be set.
*/
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
/**
* @brief Function for clearing a GPIO pin.
*
* For this function to have any effect, the pin must be configured as an output.
*
* @param pin_number Specifies the pin number to clear.
*/
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
/**
* @brief Function for toggling a GPIO pin.
*
* For this function to have any effect, the pin must be configured as an output.
*
* @param pin_number Specifies the pin number to toggle.
*/
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
/**
* @brief Function for writing a value to a GPIO pin.
*
* For this function to have any effect, the pin must be configured as an output.
*
* @param pin_number Specifies the pin number 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.
*
* If the value returned by this function is to be valid, the pin's input buffer must be connected.
*
* @param pin_number Specifies the pin number to read.
*
* @return 0 if the pin input level is low. Positive value if the pin is high.
*/
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
/**
* @brief Function for reading the output level of a GPIO pin.
*
* @param pin_number Specifies the pin number to read.
*
* @return 0 if the pin output level is low. Positive value if pin output is high.
*/
__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number);
/**
* @brief Function for reading the sense configuration of a GPIO pin.
*
* @param pin_number Specifies the pin number to read.
*
* @return Sense configuration.
*/
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number);
/**
* @brief Function for reading the direction configuration of a GPIO pin.
*
* @param pin_number Specifies the pin number to read.
*
* @return Direction configuration.
*/
__STATIC_INLINE nrf_gpio_pin_dir_t nrf_gpio_pin_dir_get(uint32_t pin_number);
/**
* @brief Function for reading the status of GPIO pin input buffer.
*
* @param pin_number Pin number to be read.
*
* @retval Input buffer configuration.
*/
__STATIC_INLINE nrf_gpio_pin_input_t nrf_gpio_pin_input_get(uint32_t pin_number);
/**
* @brief Function for reading the pull configuration of a GPIO pin.
*
* @param pin_number Specifies the pin number to read.
*
* @retval Pull configuration.
*/
__STATIC_INLINE nrf_gpio_pin_pull_t nrf_gpio_pin_pull_get(uint32_t pin_number);
/**
* @brief Function for setting output direction on the selected pins on the given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param out_mask Mask specifying the pins to set as output.
*/
__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask);
/**
* @brief Function for setting input direction on selected pins on a given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param in_mask Mask that specifies the pins to be set as input.
*/
__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask);
/**
* @brief Function for writing the direction configuration of the GPIO pins in the given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param dir_mask Mask that specifies the direction of pins. Bit set means that the given pin is configured as output.
*/
__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t dir_mask);
/**
* @brief Function for reading the direction configuration of a GPIO port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Pin configuration of the current direction settings. Bit set means that the given pin is configured as output.
*/
__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg);
/**
* @brief Function for reading the input signals of the GPIO pins on the given port.
*
* @param p_reg Pointer to the peripheral registers structure.
*
* @return Port input values.
*/
__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg);
/**
* @brief Function for reading the output signals of the GPIO pins on the given port.
*
* @param p_reg Pointer to the peripheral registers structure.
*
* @return Port output values.
*/
__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg);
/**
* @brief Function for writing the GPIO pins output on a given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param value Output port mask.
*/
__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value);
/**
* @brief Function for setting high level on selected the GPIO pins on the given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param set_mask Mask with pins to be set as logical high level.
*/
__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask);
/**
* @brief Function for setting low level on selected the GPIO pins on the given port.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param clr_mask Mask with pins to be set as logical low level.
*/
__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask);
/**
* @brief Function for reading pin state of multiple consecutive ports.
*
* @param start_port Index of the first port to read.
* @param length Number of ports to read.
* @param p_masks Pointer to output array where port states will be stored.
*/
__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks);
#if defined(NRF_GPIO_LATCH_PRESENT)
/**
* @brief Function for reading latch state of multiple consecutive ports.
*
* @param start_port Index of the first port to read.
* @param length Number of ports to read.
* @param p_masks Pointer to output array where latch states will be stored.
*/
__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
uint32_t length,
uint32_t * p_masks);
/**
* @brief Function for reading and immediate clearing latch state of multiple consecutive ports.
*
* @param start_port Index of the first port to read and clear.
* @param length Number of ports to read and clear.
* @param p_masks Pointer to output array where latch states will be stored.
*/
__STATIC_INLINE void nrf_gpio_latches_read_and_clear(uint32_t start_port,
uint32_t length,
uint32_t * p_masks);
/**
* @brief Function for reading latch state of single pin.
*
* @param pin_number Pin number.
*
* @return 0 if latch is not set. Positive value otherwise.
*/
__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number);
/**
* @brief Function for clearing latch state of a single pin.
*
* @param pin_number Pin number.
*/
__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number);
#endif // defined(NRF_GPIO_LATCH_PRESENT)
/**
* @brief Function for checking if provided pin is present on the MCU.
*
* @param[in] pin_number Number of the pin to be checked.
*
* @retval true Pin is present.
* @retval false Pin is not present.
*/
__STATIC_INLINE bool nrf_gpio_pin_present_check(uint32_t pin_number);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
/**
* @brief Function for extracting port and the relative pin number from the absolute pin number.
*
* @param[in,out] p_pin Pointer to the absolute pin number overriden by the pin number that is relative to the port.
*
* @return Pointer to port register set.
*/
__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin)
{
NRFX_ASSERT(nrf_gpio_pin_present_check(*p_pin));
#if (GPIO_COUNT == 1)
return NRF_P0;
#else
if (*p_pin < P0_PIN_NUM)
{
return NRF_P0;
}
else
{
*p_pin = *p_pin & 0x1F;
return NRF_P1;
}
#endif
}
__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_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
reg->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)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
reg->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)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
reg->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)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
reg->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk;
reg->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_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
reg->DIRSET = (1UL << pin_number);
}
}
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
nrf_gpio_port_out_set(reg, 1UL << pin_number);
}
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
nrf_gpio_port_out_clear(reg, 1UL << pin_number);
}
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
uint32_t pins_state = reg->OUT;
reg->OUTSET = (~pins_state & (1UL << pin_number));
reg->OUTCLR = (pins_state & (1UL << pin_number));
}
__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)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return ((nrf_gpio_port_in_read(reg) >> pin_number) & 1UL);
}
__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return ((nrf_gpio_port_out_read(reg) >> pin_number) & 1UL);
}
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return (nrf_gpio_pin_sense_t)((reg->PIN_CNF[pin_number] &
GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos);
}
__STATIC_INLINE nrf_gpio_pin_dir_t nrf_gpio_pin_dir_get(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return (nrf_gpio_pin_dir_t)((reg->PIN_CNF[pin_number] &
GPIO_PIN_CNF_DIR_Msk) >> GPIO_PIN_CNF_DIR_Pos);
}
__STATIC_INLINE nrf_gpio_pin_input_t nrf_gpio_pin_input_get(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return (nrf_gpio_pin_input_t)((reg->PIN_CNF[pin_number] &
GPIO_PIN_CNF_INPUT_Msk) >> GPIO_PIN_CNF_INPUT_Pos);
}
__STATIC_INLINE nrf_gpio_pin_pull_t nrf_gpio_pin_pull_get(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return (nrf_gpio_pin_pull_t)((reg->PIN_CNF[pin_number] &
GPIO_PIN_CNF_PULL_Msk) >> GPIO_PIN_CNF_PULL_Pos);
}
__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask)
{
p_reg->DIRSET = out_mask;
}
__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask)
{
p_reg->DIRCLR = in_mask;
}
__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t value)
{
p_reg->DIR = value;
}
__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg)
{
return p_reg->DIR;
}
__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg)
{
return p_reg->IN;
}
__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg)
{
return p_reg->OUT;
}
__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value)
{
p_reg->OUT = value;
}
__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask)
{
p_reg->OUTSET = set_mask;
}
__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask)
{
p_reg->OUTCLR = clr_mask;
}
__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks)
{
NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
NRFX_ASSERT(start_port + length <= GPIO_COUNT);
uint32_t i;
for (i = start_port; i < (start_port + length); i++)
{
*p_masks = nrf_gpio_port_in_read(gpio_regs[i]);
p_masks++;
}
}
#if defined(NRF_GPIO_LATCH_PRESENT)
__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port,
uint32_t length,
uint32_t * p_masks)
{
NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
uint32_t i;
for (i = start_port; i < (start_port + length); i++)
{
*p_masks = gpio_regs[i]->LATCH;
p_masks++;
}
}
__STATIC_INLINE void nrf_gpio_latches_read_and_clear(uint32_t start_port,
uint32_t length,
uint32_t * p_masks)
{
NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST;
uint32_t i;
for (i = start_port; i < (start_port + length); i++)
{
*p_masks = gpio_regs[i]->LATCH;
// The LATCH register is cleared by writing a '1' to the bit that shall be cleared.
gpio_regs[i]->LATCH = *p_masks;
p_masks++;
}
}
__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
return (reg->LATCH & (1 << pin_number)) ? 1 : 0;
}
__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number)
{
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
reg->LATCH = (1 << pin_number);
}
#endif // defined(NRF_GPIO_LATCH_PRESENT)
__STATIC_INLINE bool nrf_gpio_pin_present_check(uint32_t pin_number)
{
uint32_t port = pin_number >> 5;
uint32_t mask = 0;
switch (port)
{
#ifdef P0_FEATURE_PINS_PRESENT
case 0:
mask = P0_FEATURE_PINS_PRESENT;
#if defined(NRF52820_XXAA) && defined(DEVELOP_IN_NRF52833)
/* Allow use of the following additional GPIOs that are connected to LEDs and buttons
* on the nRF52833 DK:
* - P0.11 - Button 1
* - P0.12 - Button 2
* - P0.13 - LED 1
* - P0.24 - Button 3
* - P0.25 - Button 4
*/
mask |= 0x03003800;
#endif // defined(NRF52820_XXAA) && defined(DEVELOP_IN_NRF52833)
break;
#endif
#ifdef P1_FEATURE_PINS_PRESENT
case 1:
mask = P1_FEATURE_PINS_PRESENT;
break;
#endif
}
pin_number &= 0x1F;
return (mask & (1UL << pin_number)) ? true : false;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_GPIO_H__
+582
View File
@@ -0,0 +1,582 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_GPIOTE_H__
#define NRF_GPIOTE_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_gpiote_hal GPIOTE HAL
* @{
* @ingroup nrf_gpiote
* @brief Hardware access layer (HAL) for managing the GPIOTE peripheral.
*/
#if defined(GPIOTE_CONFIG_PORT_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Mask for covering port and pin bits in registers. */
#define GPIOTE_CONFIG_PORT_PIN_Msk (GPIOTE_CONFIG_PORT_Msk | GPIOTE_CONFIG_PSEL_Msk)
#else
#define GPIOTE_CONFIG_PORT_PIN_Msk GPIOTE_CONFIG_PSEL_Msk
#endif
/** @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;
/** @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 GPIOTE tasks. */
typedef enum
{
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 (GPIOTE_CH_NUM > 4) || defined(__NRFX_DOXYGEN__)
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
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
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. */
#endif
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
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
} nrf_gpiote_tasks_t;
/** @brief GPIOTE events. */
typedef enum
{
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 (GPIOTE_CH_NUM > 4) || defined(__NRFX_DOXYGEN__)
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. */
} nrf_gpiote_events_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 (GPIOTE_CH_NUM > 4) || defined(__NRFX_DOXYGEN__)
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 (GPIOTE_CH_NUM == 4) || defined(__NRFX_DOXYGEN__)
/** @brief Mask holding positions of available GPIOTE input interrupts. */
#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)
#else
#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)
#endif
/**
* @brief Function for activating the specified 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 the specified GPIOTE task.
*
* @param[in] task Task.
*
* @return Address of the specified task.
*/
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task);
/**
* @brief Function for getting the state of the specified GPIOTE event.
*
* @param[in] event Event.
*
* @retval true The event is set.
* @retval false The event is not set.
*/
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event);
/**
* @brief Function for clearing the specified 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 the specified GPIOTE event.
*
* @param[in] event Event.
*
* @return Address of the specified event.
*/
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event);
/**
* @brief Function for enabling interrupts.
*
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask);
/**
* @brief Function for disabling interrupts.
*
* @param[in] mask Mask of interrupts 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 interrupts to be checked.
*
* @return Mask with enabled interrupts.
*/
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* GPIOTE task.
*
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_gpiote_subscribe_set(nrf_gpiote_tasks_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* GPIOTE task.
*
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_gpiote_subscribe_clear(nrf_gpiote_tasks_t task);
/**
* @brief Function for setting the publish configuration for a given
* GPIOTE event.
*
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_gpiote_publish_set(nrf_gpiote_events_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* GPIOTE event.
*
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_gpiote_publish_clear(nrf_gpiote_events_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @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 the 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 the specified 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);
/**@brief Function for checking if particular Task-Event is enabled.
*
* @param[in] idx Task-Event index.
*
* @retval true The Task-Event mode is set to Task or Event.
* @retval false The Task-Event mode is set to Disabled.
*/
__STATIC_INLINE bool nrf_gpiote_te_is_enabled(uint32_t idx);
/**
* @brief Function for getting the OUT task associated with the specified GPIOTE channel.
*
* @param[in] index Channel index.
*
* @return Requested OUT task.
*/
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_out_task_get(uint8_t index);
#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the SET task associated with the specified GPIOTE channel.
*
* @param[in] index Channel index.
*
* @return Requested SET task.
*/
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_set_task_get(uint8_t index);
#endif
#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the CLR task associated with the specified GPIOTE channel.
*
* @param[in] index Channel index.
*
* @return Requested CLR task.
*/
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_clr_task_get(uint8_t index);
#endif
/**
* @brief Function for getting the IN event associated with the specified GPIOTE channel.
*
* @param[in] index Channel index.
*
* @return Requested IN event.
*/
__STATIC_INLINE nrf_gpiote_events_t nrf_gpiote_in_event_get(uint8_t index);
#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);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_gpiote_subscribe_set(nrf_gpiote_tasks_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_GPIOTE + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | GPIOTE_SUBSCRIBE_OUT_EN_Msk);
}
__STATIC_INLINE void nrf_gpiote_subscribe_clear(nrf_gpiote_tasks_t task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_GPIOTE + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_gpiote_publish_set(nrf_gpiote_events_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_GPIOTE + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | GPIOTE_PUBLISH_IN_EN_Msk);
}
__STATIC_INLINE void nrf_gpiote_publish_clear(nrf_gpiote_events_t event)
{
*((volatile uint32_t *) ((uint8_t *) NRF_GPIOTE + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__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_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_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_PORT_PIN_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;
#ifdef NRF51
/* 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 not existing, 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_PORT_PIN_Msk);
__NOP();
__NOP();
__NOP();
#endif
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_PORT_PIN_Msk |
GPIOTE_CONFIG_POLARITY_Msk |
GPIOTE_CONFIG_OUTINIT_Msk);
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_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;
}
__STATIC_INLINE bool nrf_gpiote_te_is_enabled(uint32_t idx)
{
return (NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_MODE_Msk) != GPIOTE_CONFIG_MODE_Disabled;
}
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_out_task_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_GPIOTE->TASKS_OUT));
return (nrf_gpiote_tasks_t)NRFX_OFFSETOF(NRF_GPIOTE_Type, TASKS_OUT[index]);
}
#if defined(GPIOTE_FEATURE_SET_PRESENT)
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_set_task_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_GPIOTE->TASKS_SET));
return (nrf_gpiote_tasks_t)NRFX_OFFSETOF(NRF_GPIOTE_Type, TASKS_SET[index]);
}
#endif
#if defined(GPIOTE_FEATURE_CLR_PRESENT)
__STATIC_INLINE nrf_gpiote_tasks_t nrf_gpiote_clr_task_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_GPIOTE->TASKS_CLR));
return (nrf_gpiote_tasks_t)NRFX_OFFSETOF(NRF_GPIOTE_Type, TASKS_CLR[index]);
}
#endif
__STATIC_INLINE nrf_gpiote_events_t nrf_gpiote_in_event_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_GPIOTE->EVENTS_IN));
return (nrf_gpiote_events_t)NRFX_OFFSETOF(NRF_GPIOTE_Type, EVENTS_IN[index]);
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif
+278
View File
@@ -0,0 +1,278 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_KMU_H__
#define NRF_KMU_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_kmu_hal KMU HAL
* @{
* @ingroup nrf_kmu
* @brief Hardware access layer for managing the Key Management Unit (KMU) peripheral.
*/
/** @brief KMU tasks. */
typedef enum
{
NRF_KMU_TASK_PUSH_KEYSLOT = offsetof(NRF_KMU_Type, TASKS_PUSH_KEYSLOT), ///< Push a key slot over secure APB.
} nrf_kmu_task_t;
/** @brief KMU events. */
typedef enum
{
NRF_KMU_EVENT_KEYSLOT_PUSHED = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_PUSHED), ///< Key successfully pushed over secure APB.
NRF_KMU_EVENT_KEYSLOT_REVOKED = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_REVOKED), ///< Key has been revoked and cannot be tasked for selection.
NRF_KMU_EVENT_KEYSLOT_ERROR = offsetof(NRF_KMU_Type, EVENTS_KEYSLOT_ERROR) ///< No key slot selected or no destination address defined or error during push mechanism.
} nrf_kmu_event_t;
/** @brief KMU interrupts. */
typedef enum
{
NRF_KMU_INT_PUSHED_MASK = KMU_INTEN_KEYSLOT_PUSHED_Msk, ///< Interrupt on KEYSLOT_PUSHED event.
NRF_KMU_INT_REVOKED_MASK = KMU_INTEN_KEYSLOT_REVOKED_Msk, ///< Interrupt on KEYSLOT_REVOKED event.
NRF_KMU_INT_ERROR_MASK = KMU_INTEN_KEYSLOT_ERROR_Msk ///< Interrupt on KEYSLOT_ERROR event.
} nrf_kmu_int_mask_t;
/** @brief KMU operation status. */
typedef enum
{
NRF_KMU_STATUS_BLOCKED_MASK = KMU_STATUS_BLOCKED_Msk, ///< Access violation detected and blocked.
NRF_KMU_STATUS_SELECTED_MASK = KMU_STATUS_SELECTED_Msk, ///< Key slot ID successfully selected by KMU
} nrf_kmu_status_t;
/**
* @brief Function for activating a specific KMU task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_kmu_task_trigger(NRF_KMU_Type * p_reg, nrf_kmu_task_t task);
/**
* @brief Function for getting the address of a specific KMU task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Requested task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_kmu_task_address_get(NRF_KMU_Type const * p_reg, nrf_kmu_task_t task);
/**
* @brief Function for clearing a specific KMU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_kmu_event_clear(NRF_KMU_Type * p_reg, nrf_kmu_event_t event);
/**
* @brief Function for retrieving the state of the KMU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_kmu_event_check(NRF_KMU_Type const * p_reg, nrf_kmu_event_t event);
/**
* @brief Function for getting the address of a specific KMU event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_kmu_event_address_get(NRF_KMU_Type const * p_reg,
nrf_kmu_event_t event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_kmu_int_enable(NRF_KMU_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_kmu_int_disable(NRF_KMU_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] kmu_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_kmu_int_enable_check(NRF_KMU_Type const * p_reg,
nrf_kmu_int_mask_t kmu_int);
/**
* @brief Function for retrieving the state of interrupts.
*
* Function returns bitmask. Please use @ref nrf_kmu_int_mask_t to check interrupts status.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Bitmask with pending interrupts bits.
*/
__STATIC_INLINE uint32_t nrf_kmu_intpend_get(NRF_KMU_Type const * p_reg);
/**
* @brief Function for getting status bits of the KMU operation.
*
* Function returns bitmask. Please use @ref nrf_kmu_status_t to check operations status.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Bitmask with operation status bits.
*/
__STATIC_INLINE uint32_t nrf_kmu_status_get(NRF_KMU_Type const * p_reg);
/**
* @brief Function for selecting the key slot ID.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] keyslot_id Key slot ID to be read over AHB or pushed over
* secure APB when TASKS_PUSH_KEYSLOT is started.
*/
__STATIC_INLINE void nrf_kmu_keyslot_set(NRF_KMU_Type * p_reg, uint8_t keyslot_id);
/**
* @brief Function for getting the key slot ID.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Key slot ID.
*/
__STATIC_INLINE uint8_t nrf_kmu_keyslot_get(NRF_KMU_Type const * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_kmu_task_trigger(NRF_KMU_Type * p_reg, nrf_kmu_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_kmu_task_address_get(NRF_KMU_Type const * p_reg, nrf_kmu_task_t task)
{
return ((uint32_t)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_kmu_event_clear(NRF_KMU_Type * p_reg, nrf_kmu_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
}
__STATIC_INLINE bool nrf_kmu_event_check(NRF_KMU_Type const * p_reg, nrf_kmu_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_kmu_event_address_get(NRF_KMU_Type const * p_reg,
nrf_kmu_event_t event)
{
return ((uint32_t)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_kmu_int_enable(NRF_KMU_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_kmu_int_disable(NRF_KMU_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_kmu_int_enable_check(NRF_KMU_Type const * p_reg,
nrf_kmu_int_mask_t kmu_int)
{
return (bool)(p_reg->INTENSET & kmu_int);
}
__STATIC_INLINE uint32_t nrf_kmu_intpend_get(NRF_KMU_Type const * p_reg)
{
return p_reg->INTPEND;
}
__STATIC_INLINE uint32_t nrf_kmu_status_get(NRF_KMU_Type const * p_reg)
{
return p_reg->STATUS;
}
__STATIC_INLINE void nrf_kmu_keyslot_set(NRF_KMU_Type * p_reg, uint8_t keyslot_id)
{
p_reg->SELECTKEYSLOT = (uint32_t) keyslot_id;
}
__STATIC_INLINE uint8_t nrf_kmu_keyslot_get(NRF_KMU_Type const * p_reg)
{
return (uint8_t) p_reg->SELECTKEYSLOT;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_KMU_H__
+185
View File
@@ -0,0 +1,185 @@
/**
* Copyright (c) 2019 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_MPU_H__
#define NRF_MPU_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_mpu_hal MPU HAL
* @{
* @ingroup nrf_mpu
* @brief Hardware access layer for managing the Memory Protection Unit (MPU) peripheral.
*/
/**
* @brief Macro for getting MPU region configuration mask for the specified peripheral.
*
* @param[in] base_addr Peripheral base address.
*
* @return MPU configuration mask for the specified peripheral.
*/
#define NRF_MPU_PERIPHERAL_MASK_GET(base_addr) (1UL << NRFX_PERIPHERAL_ID_GET(base_addr))
/**
* @brief Function for setting the size of the RAM region 0.
*
* When memory protection is enabled, the Memory Protection Unit enforces
* runtime protection and readback protection of resources classified as region 0.
* See the product specification for more information.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] size Size of the RAM region 0, in bytes. Must be word-aligned.
*/
__STATIC_INLINE void nrf_mpu_region0_ram_size_set(NRF_MPU_Type * p_reg, uint32_t size);
/**
* @brief Function for configuring specified peripherals in the memory region 0.
*
* When the memory protection is enabled, the Memory Protection Unit enforces
* runtime protection and readback protection of resources classified as region 0.
* See the product specification for more information.
*
* After reset, all peripherals are configured as *not* assigned to region 0.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] peripheral_mask Mask that specifies peripherals to be configured in the memory region 0.
* Compose this mask using @ref NRF_MPU_PERIPHERAL_MASK_GET macro.
*/
__STATIC_INLINE void nrf_mpu_region0_peripherals_set(NRF_MPU_Type * p_reg,
uint32_t peripheral_mask);
/**
* @brief Function for getting the bitmask that specifies peripherals configured in the memory region 0.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Bitmask representing peripherals configured in region 0.
*/
__STATIC_INLINE uint32_t nrf_mpu_region0_peripherals_get(NRF_MPU_Type const * p_reg);
/**
* @brief Function for enabling protection for specified non-volatile memory blocks.
*
* Blocks are arranged into groups of 32 blocks each. Each block size is 4 kB.
* Any attempt to write or erase a protected block will result in hard fault.
* The memory block protection can be disabled only by resetting the device.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] group_idx Non-volatile memory group containing memory blocks to protect.
* @param[in] block_mask Non-volatile memory blocks to protect. Each bit in bitmask represents
* one memory block in the specified group.
*/
__STATIC_INLINE void nrf_mpu_nvm_blocks_protection_enable(NRF_MPU_Type * p_reg,
uint8_t group_idx,
uint32_t block_mask);
/**
* @brief Function for setting the non-volatile memory (NVM) protection during debug.
*
* NVM protection during debug is disabled by default.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable True if NVM protection during debug is to be enabled.
* False if otherwise.
*/
__STATIC_INLINE void nrf_mpu_nvm_protection_in_debug_set(NRF_MPU_Type * p_reg,
bool enable);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_mpu_region0_ram_size_set(NRF_MPU_Type * p_reg, uint32_t size)
{
NRFX_ASSERT(nrfx_is_word_aligned((const void *)size));
p_reg->RLENR0 = size;
}
__STATIC_INLINE void nrf_mpu_region0_peripherals_set(NRF_MPU_Type * p_reg,
uint32_t peripheral_mask)
{
p_reg->PERR0 = peripheral_mask;
}
__STATIC_INLINE uint32_t nrf_mpu_region0_peripherals_get(NRF_MPU_Type const * p_reg)
{
return p_reg->PERR0;
}
__STATIC_INLINE void nrf_mpu_nvm_blocks_protection_enable(NRF_MPU_Type * p_reg,
uint8_t group_idx,
uint32_t block_mask)
{
switch (group_idx)
{
case 0:
p_reg->PROTENSET0 = block_mask;
break;
case 1:
p_reg->PROTENSET1 = block_mask;
break;
default:
NRFX_ASSERT(false);
break;
}
}
__STATIC_INLINE void nrf_mpu_nvm_protection_in_debug_set(NRF_MPU_Type * p_reg,
bool enable)
{
p_reg->DISABLEINDEBUG =
(enable ? 0 : MPU_DISABLEINDEBUG_DISABLEINDEBUG_Msk);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_MPU_H__
+425
View File
@@ -0,0 +1,425 @@
/**
* Copyright (c) 2019 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_MWU_H__
#define NRF_MWU_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_mwu_hal MWU HAL
* @{
* @ingroup nrf_mwu
* @brief Hardware access layer for managing the Memory Watch Unit (MWU) peripheral.
*/
/** @brief MWU events. */
typedef enum
{
NRF_MWU_EVENT_REGION0_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[0].WA), ///< Write access to region 0 detected.
NRF_MWU_EVENT_REGION0_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[0].RA), ///< Read access to region 0 detected.
NRF_MWU_EVENT_REGION1_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[1].WA), ///< Write access to region 1 detected.
NRF_MWU_EVENT_REGION1_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[1].RA), ///< Read access to region 1 detected.
NRF_MWU_EVENT_REGION2_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[2].WA), ///< Write access to region 2 detected.
NRF_MWU_EVENT_REGION2_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[2].RA), ///< Read access to region 2 detected.
NRF_MWU_EVENT_REGION3_WRITE = offsetof(NRF_MWU_Type, EVENTS_REGION[3].WA), ///< Write access to region 3 detected.
NRF_MWU_EVENT_REGION3_READ = offsetof(NRF_MWU_Type, EVENTS_REGION[3].RA), ///< Read access to region 3 detected.
NRF_MWU_EVENT_PREGION0_WRITE = offsetof(NRF_MWU_Type, EVENTS_PREGION[0].WA), ///< Write access to peripheral region 0 detected.
NRF_MWU_EVENT_PREGION0_READ = offsetof(NRF_MWU_Type, EVENTS_PREGION[0].RA), ///< Read access to peripheral region 0 detected.
NRF_MWU_EVENT_PREGION1_WRITE = offsetof(NRF_MWU_Type, EVENTS_PREGION[1].WA), ///< Write access to peripheral region 1 detected.
NRF_MWU_EVENT_PREGION1_READ = offsetof(NRF_MWU_Type, EVENTS_PREGION[1].RA), ///< Read access to peripheral region 1 detected.
} nrf_mwu_event_t;
/** @brief MWU interrupt masks. */
typedef enum
{
NRF_MWU_INT_REGION0_WRITE_MASK = MWU_INTEN_REGION0WA_Msk, ///< Interrupt on REGION[0].WA event.
NRF_MWU_INT_REGION0_READ_MASK = MWU_INTEN_REGION0RA_Msk, ///< Interrupt on REGION[0].RA event.
NRF_MWU_INT_REGION1_WRITE_MASK = MWU_INTEN_REGION1WA_Msk, ///< Interrupt on REGION[1].WA event.
NRF_MWU_INT_REGION1_READ_MASK = MWU_INTEN_REGION1RA_Msk, ///< Interrupt on REGION[1].RA event.
NRF_MWU_INT_REGION2_WRITE_MASK = MWU_INTEN_REGION2WA_Msk, ///< Interrupt on REGION[2].WA event.
NRF_MWU_INT_REGION2_READ_MASK = MWU_INTEN_REGION2RA_Msk, ///< Interrupt on REGION[2].RA event.
NRF_MWU_INT_REGION3_WRITE_MASK = MWU_INTEN_REGION3WA_Msk, ///< Interrupt on REGION[3].WA event.
NRF_MWU_INT_REGION3_READ_MASK = MWU_INTEN_REGION3RA_Msk, ///< Interrupt on REGION[3].RA event.
NRF_MWU_INT_PREGION0_WRITE_MASK = MWU_INTEN_PREGION0WA_Msk, ///< Interrupt on PREGION[0].WA event.
NRF_MWU_INT_PREGION0_READ_MASK = MWU_INTEN_PREGION0RA_Msk, ///< Interrupt on PREGION[0].RA event.
NRF_MWU_INT_PREGION1_WRITE_MASK = MWU_INTEN_PREGION1WA_Msk, ///< Interrupt on PREGION[1].WA event.
NRF_MWU_INT_PREGION1_READ_MASK = MWU_INTEN_PREGION1RA_Msk, ///< Interrupt on PREGION[1].RA event.
} nrf_mwu_int_mask_t;
/** @brief MWU region watch masks. */
typedef enum
{
NRF_MWU_WATCH_REGION0_WRITE = MWU_REGIONEN_RGN0WA_Msk, ///< Region 0 write access watch mask.
NRF_MWU_WATCH_REGION0_READ = MWU_REGIONEN_RGN0RA_Msk, ///< Region 0 read access watch mask.
NRF_MWU_WATCH_REGION1_WRITE = MWU_REGIONEN_RGN1WA_Msk, ///< Region 1 write access watch mask.
NRF_MWU_WATCH_REGION1_READ = MWU_REGIONEN_RGN1RA_Msk, ///< Region 1 read access watch mask.
NRF_MWU_WATCH_REGION2_WRITE = MWU_REGIONEN_RGN2WA_Msk, ///< Region 2 write access watch mask.
NRF_MWU_WATCH_REGION2_READ = MWU_REGIONEN_RGN2RA_Msk, ///< Region 2 read access watch mask.
NRF_MWU_WATCH_REGION3_WRITE = MWU_REGIONEN_RGN3WA_Msk, ///< Region 3 write access watch mask.
NRF_MWU_WATCH_REGION3_READ = MWU_REGIONEN_RGN3RA_Msk, ///< Region 3 read access watch mask.
NRF_MWU_WATCH_PREGION0_WRITE = MWU_REGIONEN_PRGN0WA_Msk, ///< Peripheral region 0 write access watch mask.
NRF_MWU_WATCH_PREGION0_READ = MWU_REGIONEN_PRGN0RA_Msk, ///< Peripheral region 0 read access watch mask.
NRF_MWU_WATCH_PREGION1_WRITE = MWU_REGIONEN_PRGN1WA_Msk, ///< Peripheral region 1 write access watch mask.
NRF_MWU_WATCH_PREGION1_READ = MWU_REGIONEN_PRGN1RA_Msk, ///< Peripheral region 1 read access watch mask.
} nrf_mwu_region_watch_t;
/**
* @brief Function for retrieving the state of the MWU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_mwu_event_check(NRF_MWU_Type const * p_reg,
nrf_mwu_event_t event);
/**
* @brief Function for clearing a specific MWU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_mwu_event_clear(NRF_MWU_Type * p_reg,
nrf_mwu_event_t event);
/**
* @brief Function for getting the address of a specific MWU event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Requested event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_mwu_event_address_get(NRF_MWU_Type const * p_reg,
nrf_mwu_event_t event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] int_mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_mwu_int_enable(NRF_MWU_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for retrieving the state of a specific interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mwu_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_mwu_int_enable_check(NRF_MWU_Type const * p_reg,
nrf_mwu_int_mask_t mwu_int);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] int_mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_mwu_int_disable(NRF_MWU_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for enabling specified non-maskable interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] int_mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_mwu_nmi_enable(NRF_MWU_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for retrieving the state of a specific non-maskable interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mwu_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_mwu_nmi_enable_check(NRF_MWU_Type const * p_reg,
nrf_mwu_int_mask_t mwu_int);
/**
* @brief Function for disabling specified non-maskable interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] int_mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_mwu_nmi_disable(NRF_MWU_Type * p_reg, uint32_t int_mask);
/**
* @brief Function for setting address range of the specified user region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_idx Region number to configure.
* @param[in] start_addr Memory address defining the beginning of the region.
* @param[in] end_addr Memory address defining the end of the region.
*/
__STATIC_INLINE void nrf_mwu_user_region_range_set(NRF_MWU_Type * p_reg,
uint8_t region_idx,
uint32_t start_addr,
uint32_t end_addr);
/**
* @brief Function for enabling memory access watch mechanism.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] reg_watch_mask Mask that defines regions and access types to watch.
* Compose this mask from @ref nrf_mwu_region_watch_t values.
*/
__STATIC_INLINE void nrf_mwu_region_watch_enable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask);
/**
* @brief Function for disabling memory access watch mechanism.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] reg_watch_mask Mask that defines regions and access types to stop watching.
* Compose this mask from @ref nrf_mwu_region_watch_t values.
*/
__STATIC_INLINE void nrf_mwu_region_watch_disable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask);
/**
* @brief Function for getting memory access watch configuration mask.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Mask that defines regions and access types being watched.
*/
__STATIC_INLINE uint32_t nrf_mwu_region_watch_get(NRF_MWU_Type const * p_reg);
/**
* @brief Function for configuring peripheral subregions for watching.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] per_reg_idx Peripheral region containing specified subregions.
* @param[in] subregion_mask Mask that defines subregions to include into the specified peripheral region.
*/
__STATIC_INLINE void nrf_mwu_subregions_configure(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask);
/**
* @brief Function for getting the mask of the write access flags of peripheral subregions
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] per_reg_idx Peripheral region containing subregions to be checked.
*
* @return Mask specifying subregions that were write accessed.
*/
__STATIC_INLINE uint32_t nrf_mwu_subregions_write_accesses_get(NRF_MWU_Type const * p_reg,
uint8_t per_reg_idx);
/**
* @brief Function for clearing write access flags of peripheral subregions.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] per_reg_idx Peripheral region containing subregion accesses to clear.
* @param[in] subregion_mask Mask that defines subregion write accesses to clear.
*/
__STATIC_INLINE void nrf_mwu_subregions_write_accesses_clear(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask);
/**
* @brief Function for getting the mask of the read access flags of peripheral subregions
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] per_reg_idx Peripheral region containing subregions to be checked.
*
* @return Mask specifying subregions that were read accessed.
*/
__STATIC_INLINE uint32_t nrf_mwu_subregions_read_accesses_get(NRF_MWU_Type const * p_reg,
uint8_t per_reg_idx);
/**
* @brief Function for clearing read access flags of peripheral subregions.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] per_reg_idx Peripheral region containing subregion accesses to clear.
* @param[in] subregion_mask Mask that defines subregion read accesses to clear.
*/
__STATIC_INLINE void nrf_mwu_subregions_read_accesses_clear(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE bool nrf_mwu_event_check(NRF_MWU_Type const * p_reg,
nrf_mwu_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_mwu_event_clear(NRF_MWU_Type * p_reg,
nrf_mwu_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_mwu_event_address_get(NRF_MWU_Type const * p_reg,
nrf_mwu_event_t event)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_mwu_int_enable(NRF_MWU_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENSET = int_mask;
}
__STATIC_INLINE bool nrf_mwu_int_enable_check(NRF_MWU_Type const * p_reg,
nrf_mwu_int_mask_t mwu_int)
{
return (bool)(p_reg->INTENSET & mwu_int);
}
__STATIC_INLINE void nrf_mwu_int_disable(NRF_MWU_Type * p_reg, uint32_t int_mask)
{
p_reg->INTENCLR = int_mask;
}
__STATIC_INLINE void nrf_mwu_nmi_enable(NRF_MWU_Type * p_reg, uint32_t int_mask)
{
p_reg->NMIENSET = int_mask;
}
__STATIC_INLINE bool nrf_mwu_nmi_enable_check(NRF_MWU_Type const * p_reg,
nrf_mwu_int_mask_t mwu_int)
{
return (bool)(p_reg->NMIENSET & mwu_int);
}
__STATIC_INLINE void nrf_mwu_nmi_disable(NRF_MWU_Type * p_reg, uint32_t int_mask)
{
p_reg->NMIENCLR = int_mask;
}
__STATIC_INLINE void nrf_mwu_user_region_range_set(NRF_MWU_Type * p_reg,
uint8_t region_idx,
uint32_t start_addr,
uint32_t end_addr)
{
NRFX_ASSERT(region_idx < NRFX_ARRAY_SIZE(NRF_MWU->REGION));
NRFX_ASSERT(end_addr >= start_addr);
p_reg->REGION[region_idx].START = start_addr;
p_reg->REGION[region_idx].END = end_addr;
}
__STATIC_INLINE void nrf_mwu_region_watch_enable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask)
{
p_reg->REGIONENSET = reg_watch_mask;
}
__STATIC_INLINE void nrf_mwu_region_watch_disable(NRF_MWU_Type * p_reg, uint32_t reg_watch_mask)
{
p_reg->REGIONENCLR = reg_watch_mask;
}
__STATIC_INLINE uint32_t nrf_mwu_region_watch_get(NRF_MWU_Type const * p_reg)
{
return p_reg->REGIONENSET;
}
__STATIC_INLINE void nrf_mwu_subregions_configure(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask)
{
NRFX_ASSERT(per_reg_idx < NRFX_ARRAY_SIZE(NRF_MWU->PREGION));
p_reg->PREGION[per_reg_idx].SUBS = subregion_mask;
}
__STATIC_INLINE uint32_t nrf_mwu_subregions_write_accesses_get(NRF_MWU_Type const * p_reg,
uint8_t per_reg_idx)
{
NRFX_ASSERT(per_reg_idx < NRFX_ARRAY_SIZE(NRF_MWU->PREGION));
return p_reg->PERREGION[per_reg_idx].SUBSTATWA;
}
__STATIC_INLINE void nrf_mwu_subregions_write_accesses_clear(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask)
{
NRFX_ASSERT(per_reg_idx < NRFX_ARRAY_SIZE(NRF_MWU->PREGION));
p_reg->PERREGION[per_reg_idx].SUBSTATWA = subregion_mask;
}
__STATIC_INLINE uint32_t nrf_mwu_subregions_read_accesses_get(NRF_MWU_Type const * p_reg,
uint8_t per_reg_idx)
{
NRFX_ASSERT(per_reg_idx < NRFX_ARRAY_SIZE(NRF_MWU->PREGION));
return p_reg->PERREGION[per_reg_idx].SUBSTATRA;
}
__STATIC_INLINE void nrf_mwu_subregions_read_accesses_clear(NRF_MWU_Type * p_reg,
uint8_t per_reg_idx,
uint32_t subregion_mask)
{
NRFX_ASSERT(per_reg_idx < NRFX_ARRAY_SIZE(NRF_MWU->PREGION));
p_reg->PERREGION[per_reg_idx].SUBSTATRA = subregion_mask;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_MWU_H__
+133
View File
@@ -0,0 +1,133 @@
/**
* Copyright (c) 2012 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
*@file
*@brief NMVC driver implementation
*/
#include <nrfx.h>
#include "nrf_nvmc.h"
static inline void wait_for_flash_ready(void)
{
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}
}
void nrf_nvmc_page_erase(uint32_t address)
{
// Enable erase.
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
__ISB();
__DSB();
// Erase the page
NRF_NVMC->ERASEPAGE = address;
wait_for_flash_ready();
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
__ISB();
__DSB();
}
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);
__ISB();
__DSB();
*(uint32_t*)address32 = value32;
wait_for_flash_ready();
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
__ISB();
__DSB();
}
void nrf_nvmc_write_word(uint32_t address, uint32_t value)
{
// Enable write.
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
__ISB();
__DSB();
*(uint32_t*)address = value;
wait_for_flash_ready();
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
__ISB();
__DSB();
}
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;
__ISB();
__DSB();
for (i = 0; i < num_words; i++)
{
((uint32_t*)address)[i] = src[i];
wait_for_flash_ready();
}
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
__ISB();
__DSB();
}
+460
View File
@@ -0,0 +1,460 @@
/**
* Copyright (c) 2012 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_NVMC_H__
#define NRF_NVMC_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_nvmc_hal_deprecated NVMC HAL (deprecated)
* @{
* @ingroup nrf_nvmc
* @brief Hardware access layer (HAL) for managing the Non-Volatile Memory Controller (NVMC) peripheral.
*
* This driver allows writing to the non-volatile memory (NVM) regions
* of the chip. 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 words in src to write.
*/
void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words);
/** @} */
/**
* @defgroup nrf_nvmc_hal NVMC HAL
* @{
* @ingroup nrf_nvmc
* @brief Hardware access layer (HAL) for managing the Non-Volatile Memory Controller (NVMC) peripheral.
*/
#if defined(NVMC_ICACHECNF_CACHEEN_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether Instruction Cache (ICache) is present. */
#define NRF_NVMC_ICACHE_PRESENT
#endif
#if defined(NVMC_ERASEPAGEPARTIALCFG_DURATION_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Symbol indicating whether the option of page partial erase is present. */
#define NRF_NVMC_PARTIAL_ERASE_PRESENT
#endif
/** @brief NVMC modes. */
typedef enum
{
NRF_NVMC_MODE_READONLY = NVMC_CONFIG_WEN_Ren, ///< NVMC in read-only mode.
NRF_NVMC_MODE_WRITE = NVMC_CONFIG_WEN_Wen, ///< NVMC in read and write mode.
NRF_NVMC_MODE_ERASE = NVMC_CONFIG_WEN_Een, ///< NVMC in read and erase mode.
#if defined(NVMC_CONFIG_WEN_PEen)
NRF_NVMC_MODE_PARTIAL_ERASE = NVMC_CONFIG_WEN_PEen ///< NVMC in read and partial erase mode.
#endif
} nrf_nvmc_mode_t;
#if defined(NVMC_CONFIGNS_WEN_Msk) || defined(__NRFX_DOXYGEN__)
/** @brief Non-secure NVMC modes. */
typedef enum
{
NRF_NVMC_NS_MODE_READONLY = NVMC_CONFIGNS_WEN_Ren, ///< Non-secure NVMC in read-only mode.
NRF_NVMC_NS_MODE_WRITE = NVMC_CONFIGNS_WEN_Wen, ///< Non-secure NVMC in read and write mode.
NRF_NVMC_NS_MODE_ERASE = NVMC_CONFIGNS_WEN_Een, ///< Non-secure NVMC in read and erase mode.
} nrf_nvmc_ns_mode_t;
#endif
#if defined(NRF_NVMC_ICACHE_PRESENT)
/** @brief NVMC ICache configuration. */
typedef enum
{
NRF_NVMC_ICACHE_DISABLE = NVMC_ICACHECNF_CACHEEN_Disabled, ///< Instruction Cache disabled.
NRF_NVMC_ICACHE_ENABLE = NVMC_ICACHECNF_CACHEEN_Enabled, ///< Instruction Cache enabled.
NRF_NVMC_ICACHE_ENABLE_WITH_PROFILING = NVMC_ICACHECNF_CACHEEN_Enabled | ///< Instruction Cache with cache profiling enabled.
NVMC_ICACHECNF_CACHEPROFEN_Msk
} nrf_nvmc_icache_config_t;
#endif // defined(NRF_NVMC_ICACHE_PRESENT)
/**
* @brief Function for checking if NVMC is ready to perform write or erase operation.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true NVMC can perform write or erase.
* @retval false NVMC is busy and cannot perform next operation yet.
*/
__STATIC_INLINE bool nrf_nvmc_ready_check(NRF_NVMC_Type const * p_reg);
#if defined(NVMC_READYNEXT_READYNEXT_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for checking if NVMC is ready to accept the next write operation.
*
* NVM writing time can be reduced by using this function.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true NVMC can accept the next write. It will be buffered and will be taken
* into account as soon as the ongoing write operation is completed.
* @retval false NVMC is busy and cannot accept the next write yet.
*/
__STATIC_INLINE bool nrf_nvmc_write_ready_check(NRF_NVMC_Type const * p_reg);
#endif // defined(NVMC_READYNEXT_READYNEXT_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the NVMC mode.
*
* Only activate erase and write modes when they are actively used.
* If Instruction Cache (ICache) is present, enabling write or erase will
* invalidate the cache and keep it invalidated.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mode Desired operating mode for NVMC.
*/
__STATIC_INLINE void nrf_nvmc_mode_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_mode_t mode);
#if defined(NVMC_CONFIGNS_WEN_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the NVMC mode for non-secure Flash page operations.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mode Desired operating mode for NVMC.
*/
__STATIC_INLINE void nrf_nvmc_nonsecure_mode_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_ns_mode_t mode);
#endif
/**
* @brief Function for starting a single page erase in the Flash memory.
*
* The NVMC mode must be correctly configured with @ref nrf_nvmc_mode_set
* before starting the erase operation.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] page_addr Address of the first word of the page to erase.
*/
__STATIC_INLINE void nrf_nvmc_page_erase_start(NRF_NVMC_Type * p_reg,
uint32_t page_addr);
#if defined(NVMC_ERASEUICR_ERASEUICR_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for starting the user information configuration registers (UICR) erase.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_nvmc_uicr_erase_start(NRF_NVMC_Type * p_reg);
#endif
/**
* @brief Function for starting the erase of the whole NVM, including UICR.
*
* This function purges all user code.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_nvmc_erase_all_start(NRF_NVMC_Type * p_reg);
#if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
/**
* @brief Function for configuring the page partial erase duration in milliseconds.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] duration_ms Page partial erase duration in milliseconds.
*/
__STATIC_INLINE void nrf_nvmc_partial_erase_duration_set(NRF_NVMC_Type * p_reg,
uint32_t duration_ms);
/**
* @brief Function for getting the current setting for the page partial erase duration.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval Interval duration setting in milliseconds.
*/
__STATIC_INLINE uint32_t nrf_nvmc_partial_erase_duration_get(NRF_NVMC_Type const * p_reg);
/**
* @brief Function for starting a partial erase operation.
*
* It must be called successively until the page erase time is reached.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] page_addr Address of the first word of the page to erase.
*/
__STATIC_INLINE void nrf_nvmc_page_partial_erase_start(NRF_NVMC_Type * p_reg,
uint32_t page_addr);
#endif // defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
#if defined(NRF_NVMC_ICACHE_PRESENT)
/**
* @brief Function for applying the Instruction Cache (ICache) configuration.
*
* Enabling the cache can increase CPU performance and reduce power
* consumption by reducing the number of wait cycles and the number
* of flash accesses.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] config ICache configuration.
*/
__STATIC_INLINE void nrf_nvmc_icache_config_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_icache_config_t config);
/**
* @brief Function for checking if ICache is enabled.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true ICache enabled.
* @retval false ICache disabled.
*/
__STATIC_INLINE bool nrf_nvmc_icache_enable_check(NRF_NVMC_Type const * p_reg);
/**
* @brief Function for checking if the ICache profiling option is enabled.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true ICache profiling enabled.
* @retval false ICache profiling disabled.
*/
__STATIC_INLINE bool nrf_nvmc_icache_profiling_enable_check(NRF_NVMC_Type const * p_reg);
/**
* @brief Function for getting the number of ICache hits.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval Number of the ICache hits.
*/
__STATIC_INLINE uint32_t nrf_nvmc_icache_hit_get(NRF_NVMC_Type const * p_reg);
/**
* @brief Function for getting the number of ICache misses.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval Number of the ICache misses.
*/
__STATIC_INLINE uint32_t nrf_nvmc_icache_miss_get(NRF_NVMC_Type const * p_reg);
/**
* @brief Function for resetting the ICache hit and miss counters.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_nvmc_icache_hit_miss_reset(NRF_NVMC_Type * p_reg);
#endif // defined(NRF_NVMC_ICACHE_PRESENT)
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE bool nrf_nvmc_ready_check(NRF_NVMC_Type const * p_reg)
{
return (bool)(p_reg->READY & NVMC_READY_READY_Msk);
}
#if defined(NVMC_READYNEXT_READYNEXT_Msk)
__STATIC_INLINE bool nrf_nvmc_write_ready_check(NRF_NVMC_Type const * p_reg)
{
return (bool)(p_reg->READYNEXT & NVMC_READYNEXT_READYNEXT_Msk);
}
#endif
__STATIC_INLINE void nrf_nvmc_mode_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_mode_t mode)
{
p_reg->CONFIG = (uint32_t)mode;
}
#if defined(NVMC_CONFIGNS_WEN_Msk)
__STATIC_INLINE void nrf_nvmc_nonsecure_mode_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_ns_mode_t mode)
{
p_reg->CONFIGNS = (uint32_t)mode;
}
#endif
__STATIC_INLINE void nrf_nvmc_page_erase_start(NRF_NVMC_Type * p_reg,
uint32_t page_addr)
{
#if defined(NRF51)
/* On nRF51, the code area can be divided into two regions: CR0 and CR1.
* The length of CR0 is specified in the CLENR0 register of UICR.
* If CLENR0 contains the 0xFFFFFFFF value, CR0 is not set.
* Moreover, the page from CR0 can be written or erased only from code
* running in CR0.*/
uint32_t cr0_len = NRF_UICR->CLENR0 == 0xFFFFFFFF ? 0 : NRF_UICR->CLENR0;
if (page_addr < cr0_len)
{
p_reg->ERASEPCR0 = page_addr;
}
else
{
p_reg->ERASEPCR1 = page_addr;
}
#elif defined(NRF52_SERIES)
p_reg->ERASEPAGE = page_addr;
#elif defined(NRF9160_XXAA)
*(volatile uint32_t *)page_addr = 0xFFFFFFFF;
(void)p_reg;
#else
#error "Unknown device."
#endif
}
#if defined(NVMC_ERASEUICR_ERASEUICR_Msk)
__STATIC_INLINE void nrf_nvmc_uicr_erase_start(NRF_NVMC_Type * p_reg)
{
p_reg->ERASEUICR = 1;
}
#endif
__STATIC_INLINE void nrf_nvmc_erase_all_start(NRF_NVMC_Type * p_reg)
{
p_reg->ERASEALL = 1;
}
#if defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
__STATIC_INLINE void nrf_nvmc_partial_erase_duration_set(NRF_NVMC_Type * p_reg,
uint32_t duration_ms)
{
p_reg->ERASEPAGEPARTIALCFG = duration_ms;
}
__STATIC_INLINE uint32_t nrf_nvmc_partial_erase_duration_get(NRF_NVMC_Type const * p_reg)
{
return p_reg->ERASEPAGEPARTIALCFG;
}
__STATIC_INLINE void nrf_nvmc_page_partial_erase_start(NRF_NVMC_Type * p_reg,
uint32_t page_addr)
{
#if defined(NVMC_ERASEPAGEPARTIAL_ERASEPAGEPARTIAL_Msk)
p_reg->ERASEPAGEPARTIAL = page_addr;
#elif defined(NRF9160_XXAA)
nrf_nvmc_page_erase_start(p_reg, page_addr);
#else
#error "Unknown device."
#endif
}
#endif // defined(NRF_NVMC_PARTIAL_ERASE_PRESENT)
#if defined(NRF_NVMC_ICACHE_PRESENT)
__STATIC_INLINE void nrf_nvmc_icache_config_set(NRF_NVMC_Type * p_reg,
nrf_nvmc_icache_config_t config)
{
p_reg->ICACHECNF = (uint32_t)config;
}
__STATIC_INLINE bool nrf_nvmc_icache_enable_check(NRF_NVMC_Type const * p_reg)
{
return (bool)(p_reg->ICACHECNF & NVMC_ICACHECNF_CACHEEN_Msk);
}
__STATIC_INLINE bool nrf_nvmc_icache_profiling_enable_check(NRF_NVMC_Type const * p_reg)
{
return (bool)(p_reg->ICACHECNF & NVMC_ICACHECNF_CACHEPROFEN_Msk);
}
__STATIC_INLINE uint32_t nrf_nvmc_icache_hit_get(NRF_NVMC_Type const * p_reg)
{
return p_reg->IHIT;
}
__STATIC_INLINE uint32_t nrf_nvmc_icache_miss_get(NRF_NVMC_Type const * p_reg)
{
return p_reg->IMISS;
}
__STATIC_INLINE void nrf_nvmc_icache_hit_miss_reset(NRF_NVMC_Type * p_reg)
{
p_reg->IHIT = 0;
p_reg->IMISS = 0;
}
#endif // defined(NRF_NVMC_ICACHE_PRESENT)
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_NVMC_H__
File diff suppressed because it is too large Load Diff
+524
View File
@@ -0,0 +1,524 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_PPI_H__
#define NRF_PPI_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_ppi_hal PPI HAL
* @{
* @ingroup nrf_ppi
* @brief Hardware access layer (HAL) for managing the Programmable Peripheral Interconnect (PPI)
* channels.
*/
/** @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. */
#if (PPI_CH_NUM > 16) || defined(__NRFX_DOXYGEN__)
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;
/** @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. */
#if (PPI_GROUP_NUM > 4) || defined(__NRFX_DOXYGEN__)
NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */
NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */
#endif
} nrf_ppi_channel_group_t;
/** @brief Definition of whether a PPI channel belongs 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;
/** @brief Definition of whether 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;
/** @brief PPI tasks. */
typedef enum
{
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. */
#if (PPI_GROUP_NUM > 4) || defined(__NRFX_DOXYGEN__)
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
} nrf_ppi_task_t;
/**
* @brief Function for enabling a given PPI channel.
*
* @details This function enables only one channel.
*
* @param[in] channel Channel to be enabled.
*/
__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel);
/**
* @brief Function for disabling a given PPI channel.
*
* @details This function disables only one channel.
*
* @param[in] channel Channel to be disabled.
*/
__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_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 be checked.
*
* @retval NRF_PPI_CHANNEL_ENABLED The channel is enabled.
* @retval NRF_PPI_CHANNEL_DISABLED The channel is not enabled.
*
*/
__STATIC_INLINE nrf_ppi_channel_enable_t nrf_ppi_channel_enable_get(nrf_ppi_channel_t channel);
/** @brief Function for disabling all PPI channels. */
__STATIC_INLINE void nrf_ppi_channel_disable_all(void);
/**
* @brief Function for enabling multiple PPI channels.
*
* @param[in] mask Channel mask.
*/
__STATIC_INLINE void nrf_ppi_channels_enable(uint32_t mask);
/**
* @brief Function for disabling multiple PPI channels.
*
* @param[in] mask Channel mask.
*/
__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t 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);
/**
* @brief Function for setting up the event endpoint for a given PPI channel.
*
* @param[in] eep Event register address.
* @param[in] channel Channel to which the given endpoint is assigned.
*/
__STATIC_INLINE void nrf_ppi_event_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep);
/**
* @brief Function for setting up the task endpoint for a given PPI channel.
*
* @param[in] tep Task register address.
* @param[in] channel Channel to which the given endpoint is assigned.
*/
__STATIC_INLINE void nrf_ppi_task_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t tep);
#if defined(PPI_FEATURE_FORKS_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @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);
/**
* @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);
#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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @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);
/**
* @brief Function for setting a PPI task.
*
* @param[in] ppi_task PPI task to be set.
*/
__STATIC_INLINE void nrf_ppi_task_trigger(nrf_ppi_task_t ppi_task);
/**
* @brief Function for getting the address of the specified PPI task register.
*
* @param[in] ppi_task PPI task.
*
* @return Address of the requested PPI task register.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_address_get(nrf_ppi_task_t ppi_task);
/**
* @brief Function for getting the PPI enable task address of the specified group.
*
* @param[in] group PPI group.
*
* @return PPI enable task address of the specified group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_enable_address_get(nrf_ppi_channel_group_t group);
/**
* @brief Function for getting the PPI disable task address of the specified group.
*
* @param[in] group PPI group.
*
* @return PPI disable task address of the specified group.
*/
__STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channel_group_t group);
/**
* @brief Function for getting the ENABLE task associated with the specified channel group.
*
* @param[in] index Channel group index.
*
* @return Requested ENABLE task.
*/
__STATIC_INLINE nrf_ppi_task_t nrf_ppi_group_enable_task_get(uint8_t index);
/**
* @brief Function for getting the DISABLE task associated with the specified channel group.
*
* @param[in] index Channel group index.
*
* @return Requested DISABLE task.
*/
__STATIC_INLINE nrf_ppi_task_t nrf_ppi_group_disable_task_get(uint8_t index);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Set << ((uint32_t) channel);
}
__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_t channel)
{
NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Clear << ((uint32_t) channel);
}
__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;
}
}
__STATIC_INLINE void nrf_ppi_channel_disable_all(void)
{
NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL);
}
__STATIC_INLINE void nrf_ppi_channels_enable(uint32_t mask)
{
NRF_PPI->CHENSET = mask;
}
__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask)
{
NRF_PPI->CHENCLR = mask;
}
__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;
}
__STATIC_INLINE void nrf_ppi_event_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t eep)
{
NRF_PPI->CH[(uint32_t) channel].EEP = eep;
}
__STATIC_INLINE void nrf_ppi_task_endpoint_setup(nrf_ppi_channel_t channel,
uint32_t tep)
{
NRF_PPI->CH[(uint32_t) channel].TEP = tep;
}
#if defined(PPI_FEATURE_FORKS_PRESENT)
__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;
}
__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
__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));
}
__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);
}
__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));
}
__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);
}
__STATIC_INLINE void nrf_ppi_channel_group_clear(nrf_ppi_channel_group_t group)
{
NRF_PPI->CHG[(uint32_t) group] = 0;
}
__STATIC_INLINE void nrf_ppi_group_enable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].EN = 1UL;
}
__STATIC_INLINE void nrf_ppi_group_disable(nrf_ppi_channel_group_t group)
{
NRF_PPI->TASKS_CHG[(uint32_t) group].DIS = 1UL;
}
__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)) = 1UL;
}
__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);
}
__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;
}
__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;
}
__STATIC_INLINE nrf_ppi_task_t nrf_ppi_group_enable_task_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_PPI->TASKS_CHG));
return (nrf_ppi_task_t)NRFX_OFFSETOF(NRF_PPI_Type, TASKS_CHG[index].EN);
}
__STATIC_INLINE nrf_ppi_task_t nrf_ppi_group_disable_task_get(uint8_t index)
{
NRFX_ASSERT(index < NRFX_ARRAY_SIZE(NRF_PPI->TASKS_CHG));
return (nrf_ppi_task_t)NRFX_OFFSETOF(NRF_PPI_Type, TASKS_CHG[index].DIS);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_PPI_H__
+751
View File
@@ -0,0 +1,751 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_PWM_H__
#define NRF_PWM_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_pwm_hal PWM HAL
* @{
* @ingroup nrf_pwm
* @brief Hardware access layer for managing the Pulse Width Modulation (PWM) peripheral.
*/
/**
* @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 Helper macro for calculating the number of 16-bit values in the specified
* array of duty cycle values.
*/
#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / sizeof(uint16_t))
/** @brief PWM tasks. */
typedef enum
{
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.
} nrf_pwm_task_t;
/** @brief PWM events. */
typedef enum
{
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 specified number of times.
} 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 internal register of the peripheral, 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 are to 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 is to 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 Function for activating the specified PWM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task);
/**
* @brief Function for getting the address of the specified PWM task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task PWM task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg,
nrf_pwm_task_t task);
/**
* @brief Function for clearing the specified PWM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event);
/**
* @brief Function for retrieving the state of the PWM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg,
nrf_pwm_event_t event);
/**
* @brief Function for getting the address of the specified PWM event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event PWM event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg,
nrf_pwm_event_t event);
/**
* @brief Function for enabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for setting the configuration of PWM shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts configuration to be set.
*/
__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for setting the configuration of PWM interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be set.
*/
__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] pwm_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg,
nrf_pwm_int_mask_t pwm_int);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* PWM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_pwm_subscribe_set(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* PWM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_pwm_subscribe_clear(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* PWM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_pwm_publish_set(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* PWM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_pwm_publish_clear(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for enabling the PWM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg);
/**
* @brief Function for disabling the PWM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg);
/**
* @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_reg Pointer to the structure of registers of the peripheral.
* @param[in] out_pins Array with pin numbers for individual PWM output channels.
*/
__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg,
uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]);
/**
* @brief Function for configuring the PWM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t seq_id,
uint32_t refresh);
/**
* @brief Function for modifying the additional time added after the sequence
* is played.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @param[in] loop_count Number of times to perform the sequence playback.
*/
__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg,
uint16_t loop_count);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg,
nrf_pwm_task_t task)
{
return ((uint32_t)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg,
nrf_pwm_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg,
nrf_pwm_event_t event)
{
return ((uint32_t)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS = mask;
}
__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg,
uint32_t mask)
{
p_reg->INTEN = mask;
}
__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg,
nrf_pwm_int_mask_t pwm_int)
{
return (bool)(p_reg->INTENSET & pwm_int);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_pwm_subscribe_set(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | PWM_SUBSCRIBE_STOP_EN_Msk);
}
__STATIC_INLINE void nrf_pwm_subscribe_clear(NRF_PWM_Type * p_reg,
nrf_pwm_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_pwm_publish_set(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | PWM_PUBLISH_STOPPED_EN_Msk);
}
__STATIC_INLINE void nrf_pwm_publish_clear(NRF_PWM_Type * p_reg,
nrf_pwm_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg)
{
p_reg->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg)
{
p_reg->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg,
uint32_t out_pins[NRF_PWM_CHANNEL_COUNT])
{
uint8_t i;
for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i)
{
p_reg->PSEL.OUT[i] = out_pins[i];
}
}
__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg,
nrf_pwm_clk_t base_clock,
nrf_pwm_mode_t mode,
uint16_t top_value)
{
NRFX_ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk);
p_reg->PRESCALER = base_clock;
p_reg->MODE = mode;
p_reg->COUNTERTOP = top_value;
}
__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg,
uint8_t seq_id,
nrf_pwm_sequence_t const * p_seq)
{
NRFX_ASSERT(p_seq != NULL);
nrf_pwm_seq_ptr_set( p_reg, seq_id, p_seq->values.p_raw);
nrf_pwm_seq_cnt_set( p_reg, seq_id, p_seq->length);
nrf_pwm_seq_refresh_set( p_reg, seq_id, p_seq->repeats);
nrf_pwm_seq_end_delay_set(p_reg, seq_id, p_seq->end_delay);
}
__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg,
uint8_t seq_id,
uint16_t const * p_values)
{
NRFX_ASSERT(seq_id <= 1);
NRFX_ASSERT(p_values != NULL);
p_reg->SEQ[seq_id].PTR = (uint32_t)p_values;
}
__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg,
uint8_t seq_id,
uint16_t length)
{
NRFX_ASSERT(seq_id <= 1);
NRFX_ASSERT(length != 0);
NRFX_ASSERT(length <= PWM_SEQ_CNT_CNT_Msk);
p_reg->SEQ[seq_id].CNT = length;
}
__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg,
uint8_t seq_id,
uint32_t refresh)
{
NRFX_ASSERT(seq_id <= 1);
NRFX_ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk);
p_reg->SEQ[seq_id].REFRESH = refresh;
}
__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg,
uint8_t seq_id,
uint32_t end_delay)
{
NRFX_ASSERT(seq_id <= 1);
NRFX_ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk);
p_reg->SEQ[seq_id].ENDDELAY = end_delay;
}
__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg,
nrf_pwm_dec_load_t dec_load,
nrf_pwm_dec_step_t dec_step)
{
p_reg->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_reg,
uint16_t loop_count)
{
p_reg->LOOP = loop_count;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_PWM_H__
File diff suppressed because it is too large Load Diff
+104
View File
@@ -0,0 +1,104 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_REGULATORS_H__
#define NRF_REGULATORS_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_regulators_hal REGULATORS HAL
* @{
* @ingroup nrf_power
* @brief Hardware access layer for managing the REGULATORS peripheral.
*/
/**
* @brief Function for enabling or disabling DCDC converter.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] enable Set true to enable or false to disable DCDC converter.
*/
__STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable);
/**
* @brief Function for putting CPU in system OFF mode.
*
* This function puts the CPU into system off mode.
* The only way to wake up the CPU is by reset.
*
* @note This function never returns.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable)
{
p_reg->DCDCEN = (enable ? REGULATORS_DCDCEN_DCDCEN_Msk : 0);
}
__STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg)
{
p_reg->SYSTEMOFF = REGULATORS_SYSTEMOFF_SYSTEMOFF_Msk;
__DSB();
/* Solution for simulated System OFF in debug mode */
while (true)
{
__WFE();
}
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_REGULATORS_H__
+260
View File
@@ -0,0 +1,260 @@
/**
* Copyright (c) 2014 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_RNG_H__
#define NRF_RNG_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_rng_hal RNG HAL
* @{
* @ingroup nrf_rng
* @brief Hardware access layer (HAL) for managing the Random Number Generator (RNG) peripheral.
*/
/** @brief RNG tasks. */
typedef enum
{
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;
/** @brief RNG events. */
typedef enum
{
NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */
} nrf_rng_event_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;
/** @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] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_rng_int_enable(uint32_t mask);
/**
* @brief Function for disabling interrupts.
*
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_rng_int_disable(uint32_t mask);
/**
* @brief Function for getting the state of the specified interrupt.
*
* @param[in] mask Interrupts to be checked.
*
* @retval true The interrupt is not enabled.
* @retval false The interrupt is enabled.
*/
__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t mask);
/**
* @brief Function for getting the address of the specified task.
*
* This function can be used by the PPI module.
*
* @param[in] rng_task The specified task.
*
* @return Address of the specified task.
*/
__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task);
/**
* @brief Function for triggering the specified task.
*
* @param[in] rng_task The specified Task.
*/
__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task);
/**
* @brief Function for getting address of the specified event.
*
* This function can be used by the PPI module.
*
* @param[in] rng_event The specified event.
*
* @return Address of the specified event.
*/
__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event);
/**
* @brief Function for clearing the specified event.
*
* @param[in] rng_event The specified event.
*/
__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event);
/**
* @brief Function for getting the state of the specified event.
*
* @param[in] rng_event The specified event.
*
* @retval true The event is not set.
* @retval false The event is set.
*/
__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event);
/**
* @brief Function for setting shortcuts.
*
* @param[in] mask Mask of shortcuts.
*/
__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t mask);
/**
* @brief Function for clearing shortcuts.
*
* @param[in] mask Mask of shortcuts.
*/
__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t 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);
/** @brief Function for enabling digital error correction. */
__STATIC_INLINE void nrf_rng_error_correction_enable(void);
/** @brief Function for disabling digital error correction. */
__STATIC_INLINE void nrf_rng_error_correction_disable(void);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_rng_int_enable(uint32_t mask)
{
NRF_RNG->INTENSET = mask;
}
__STATIC_INLINE void nrf_rng_int_disable(uint32_t mask)
{
NRF_RNG->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t mask)
{
return (bool)(NRF_RNG->INTENCLR & mask);
}
__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task)
{
return (uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_task);
}
__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task)
{
*((volatile uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event)
{
return (uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_event);
}
__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event)
{
*((volatile uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event)
{
return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + (uint32_t)rng_event));
}
__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t mask)
{
NRF_RNG->SHORTS |= mask;
}
__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t mask)
{
NRF_RNG->SHORTS &= ~mask;
}
__STATIC_INLINE uint8_t nrf_rng_random_value_get(void)
{
return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk);
}
__STATIC_INLINE void nrf_rng_error_correction_enable(void)
{
NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk;
}
__STATIC_INLINE void nrf_rng_error_correction_disable(void)
{
NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk;
}
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* NRF_RNG_H__ */
+426
View File
@@ -0,0 +1,426 @@
/**
* Copyright (c) 2014 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_RTC_H
#define NRF_RTC_H
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_rtc_hal RTC HAL
* @{
* @ingroup nrf_rtc
* @brief Hardware access layer for managing the Real Time Counter (RTC) peripheral.
*/
/** @brief Macro for getting the number of compare channels available in a given RTC instance. */
#define NRF_RTC_CC_CHANNEL_COUNT(id) NRFX_CONCAT_3(RTC, id, _CC_NUM)
/** @brief Input frequency of the RTC instance. */
#define RTC_INPUT_FREQ 32768
/** @brief Macro for converting expected frequency to prescaler setting. */
#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)(((RTC_INPUT_FREQ) / (FREQ)) - 1)
/** @brief Macro for trimming values to the RTC bit width. */
#define RTC_WRAP(val) ((val) & RTC_COUNTER_COUNTER_Msk)
/** @brief Macro for creating the interrupt bitmask for the specified compare channel. */
#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)(NRF_RTC_INT_COMPARE0_MASK) << (ch))
/** @brief Macro for obtaining the compare event for the specified channel. */
#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)((NRF_RTC_EVENT_COMPARE_0) + (ch) * sizeof(uint32_t))
/** @brief RTC tasks. */
typedef enum
{
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. */
} nrf_rtc_task_t;
/** @brief RTC events. */
typedef enum
{
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. */
} nrf_rtc_event_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_reg Pointer to the structure of registers of the peripheral.
* @param[in] ch Channel.
* @param[in] cc_val Compare value to be set.
*/
__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val);
/**
* @brief Function for returning the compare value for a channel.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ch Channel.
*
* @return COMPARE[ch] value.
*/
__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_reg, uint32_t ch);
/**
* @brief Function for enabling interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupt mask to be enabled.
*/
__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupt mask to be disabled.
*/
__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask);
/**
* @brief Function for checking if interrupts are enabled.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupt flags to be checked.
*
* @return Mask with enabled interrupts.
*/
__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_reg, uint32_t mask);
/**
* @brief Function for returning the status of currently enabled interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Value in INTEN register.
*/
__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_reg);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* RTC task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,
nrf_rtc_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* RTC task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,
nrf_rtc_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* RTC event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg,
nrf_rtc_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* RTC event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg,
nrf_rtc_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for checking if an event is pending.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Address of the event.
*
* @return Mask of pending events.
*/
__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_reg, nrf_rtc_event_t event);
/**
* @brief Function for clearing an event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be cleared.
*/
__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event);
/**
* @brief Function for returning a counter value.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Counter value.
*/
__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_reg);
/**
* @brief Function for setting a prescaler value.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] val Value to set the prescaler to.
*/
__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val);
/**
* @brief Function for returning the address of an event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg, nrf_rtc_event_t event);
/**
* @brief Function for returning the address of a task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg, nrf_rtc_task_t task);
/**
* @brief Function for starting a task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Requested task.
*/
__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task);
/**
* @brief Function for enabling events.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of event flags to be enabled.
*/
__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling an event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Requested event.
*/
__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t event);
/**
* @brief Function for getting the COMPARE event associated with the specified compare channel.
*
* @param[in] index Compare channel index.
*
* @return Requested COMPARE event.
*/
__STATIC_INLINE nrf_rtc_event_t nrf_rtc_compare_event_get(uint8_t index);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val)
{
p_reg->CC[ch] = cc_val;
}
__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_reg, uint32_t ch)
{
return p_reg->CC[ch];
}
__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_reg, uint32_t mask)
{
return (p_reg->INTENSET & mask);
}
__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_reg)
{
return p_reg->INTENSET;
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,
nrf_rtc_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | RTC_SUBSCRIBE_START_EN_Msk);
}
__STATIC_INLINE void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,
nrf_rtc_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_rtc_publish_set(NRF_RTC_Type * p_reg,
nrf_rtc_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | RTC_PUBLISH_TICK_EN_Msk);
}
__STATIC_INLINE void nrf_rtc_publish_clear(NRF_RTC_Type * p_reg,
nrf_rtc_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_reg, nrf_rtc_event_t event)
{
return *(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_reg)
{
return p_reg->COUNTER;
}
__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val)
{
NRFX_ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
p_reg->PRESCALER = val;
}
__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_reg)
{
return p_reg->PRESCALER;
}
__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_reg, nrf_rtc_event_t event)
{
return (uint32_t)p_reg + event;
}
__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_reg, nrf_rtc_task_t task)
{
return (uint32_t)p_reg + task;
}
__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task)
{
*(__IO uint32_t *)((uint32_t)p_reg + task) = 1;
}
__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask)
{
p_reg->EVTENSET = mask;
}
__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t mask)
{
p_reg->EVTENCLR = mask;
}
__STATIC_INLINE nrf_rtc_event_t nrf_rtc_compare_event_get(uint8_t index)
{
return (nrf_rtc_event_t)NRFX_OFFSETOF(NRF_RTC_Type, EVENTS_COMPARE[index]);
}
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* NRF_RTC_H */
+896
View File
@@ -0,0 +1,896 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_SAADC_H_
#define NRF_SAADC_H_
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_saadc_hal SAADC HAL
* @{
* @ingroup nrf_saadc
* @brief Hardware access layer for managing the SAADC peripheral.
*/
/** @brief Number of available SAADC channels. */
#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.
#if defined(SAADC_CH_PSELP_PSELP_VDDHDIV5) || defined(__NRFX_DOXYGEN__)
NRF_SAADC_INPUT_VDDHDIV5 = SAADC_CH_PSELP_PSELP_VDDHDIV5 ///< VDDH/5 as input.
#endif
} 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 mode. 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 channel burst mode. */
typedef enum
{
NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///< Burst mode is disabled (normal operation).
NRF_SAADC_BURST_ENABLED = SAADC_CH_CONFIG_BURST_Enabled ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM.
} nrf_saadc_burst_t;
/** @brief Analog-to-digital converter tasks. */
typedef enum
{
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 ongoing 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
{
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_DONE = offsetof(NRF_SAADC_Type, EVENTS_DONE), ///< A conversion task has been completed.
NRF_SAADC_EVENT_RESULTDONE = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE), ///< A result is ready to get transferred to RAM.
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_DONE = SAADC_INTENSET_DONE_Msk, ///< Interrupt on EVENTS_DONE event.
NRF_SAADC_INT_RESULTDONE = SAADC_INTENSET_RESULTDONE_Msk, ///< Interrupt on EVENTS_RESULTDONE event.
NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE 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, ///< Low limit type.
NRF_SAADC_LIMIT_HIGH = 1 ///< High limit type.
} nrf_saadc_limit_t;
/** @brief Type of a single ADC conversion result. */
typedef int16_t nrf_saadc_value_t;
/** @brief Analog-to-digital converter configuration structure. */
typedef struct
{
nrf_saadc_resolution_t resolution; ///< Resolution of samples.
nrf_saadc_oversample_t oversample; ///< Oversampling configuration.
nrf_saadc_value_t * buffer; ///< Pointer to sample buffer.
uint32_t buffer_size; ///< Size of the sample buffer.
} nrf_saadc_config_t;
/** @brief Analog-to-digital converter channel configuration structure. */
typedef struct
{
nrf_saadc_resistor_t resistor_p; ///< Resistor value on positive input.
nrf_saadc_resistor_t resistor_n; ///< Resistor value on negative input.
nrf_saadc_gain_t gain; ///< Gain control value.
nrf_saadc_reference_t reference; ///< Reference control value.
nrf_saadc_acqtime_t acq_time; ///< Acquisition time.
nrf_saadc_mode_t mode; ///< SAADC mode. Single-ended or differential.
nrf_saadc_burst_t burst; ///< Burst mode configuration.
nrf_saadc_input_t pin_p; ///< Input positive pin selection.
nrf_saadc_input_t pin_n; ///< Input negative pin selection.
} nrf_saadc_channel_config_t;
/**
* @brief Function for triggering the specified SAADC task.
*
* @param[in] task SAADC task.
*/
__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t task);
/**
* @brief Function for getting the address of the specified SAADC task register.
*
* @param[in] task SAADC task.
*
* @return Address of the specified SAADC task.
*/
__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t task);
/**
* @brief Function for retrieving the state of the UARTE event.
*
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t event);
/**
* @brief Function for clearing the specific SAADC event.
*
* @param[in] event SAADC event.
*/
__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t event);
/**
* @brief Function for getting the address of the specified SAADC event register.
*
* @param[in] event SAADC event.
*
* @return Address of the specified SAADC event.
*/
__STATIC_INLINE uint32_t nrf_saadc_event_address_get(nrf_saadc_event_t event);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* SAADC task.
*
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_saadc_subscribe_set(nrf_saadc_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* SAADC task.
*
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_saadc_subscribe_clear(nrf_saadc_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* SAADC event.
*
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_saadc_publish_set(nrf_saadc_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* SAADC event.
*
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_saadc_publish_clear(nrf_saadc_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting the address of the SAADC limit event register,
* as specified by the channel and the limit type.
*
* @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);
/**
* @brief Function for getting the SAADC channel monitoring limit events.
*
* @param[in] channel Channel number.
* @param[in] limit_type Low limit or high limit.
*
* @return The SAADC channel monitoring limit event.
*/
__STATIC_INLINE nrf_saadc_event_t nrf_saadc_limit_event_get(uint8_t channel,
nrf_saadc_limit_t limit_type);
/**
* @brief Function for configuring the input pins for the specified 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);
/**
* @brief Function for configuring the positive input pin for the specified SAADC channel.
*
* @param[in] channel Channel number.
* @param[in] pselp Positive input.
*/
__STATIC_INLINE void nrf_saadc_channel_pos_input_set(uint8_t channel,
nrf_saadc_input_t 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);
/**
* @brief Function for setting the configuration of SAADC interrupts.
*
* @param[in] mask Interrupts configuration to be set.
*/
__STATIC_INLINE void nrf_saadc_int_set(uint32_t mask);
/**
* @brief Function for enabling specified SAADC interrupts.
*
* @param[in] saadc_int_mask Interrupt(s) to be enabled.
*/
__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask);
/**
* @brief Function for retrieving the state of specified SAADC interrupts.
*
* @param[in] saadc_int_mask Interrupt(s) to be checked.
*
* @retval true All specified interrupts are enabled.
* @retval false At least one of the given interrupts is not enabled.
*/
__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param saadc_int_mask Interrupt(s) to be disabled.
*/
__STATIC_INLINE void nrf_saadc_int_disable(uint32_t 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.
*
* @return Interrupt mask.
*/
__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type);
/**
* @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 The SAADC is busy.
* @retval false The SAADC is not busy.
*/
__STATIC_INLINE bool nrf_saadc_busy_check(void);
/**
* @brief Function for enabling the SAADC.
*
* The analog-to-digital converter must be enabled before use.
*/
__STATIC_INLINE void nrf_saadc_enable(void);
/**
* @brief Function for disabling the SAADC.
*/
__STATIC_INLINE void nrf_saadc_disable(void);
/**
* @brief Function for checking if the SAADC is enabled.
*
* @retval true The SAADC is enabled.
* @retval false The SAADC is not enabled.
*/
__STATIC_INLINE bool nrf_saadc_enable_check(void);
/**
* @brief Function for initializing the SAADC result buffer.
*
* @param[in] p_buffer Pointer to the result buffer.
* @param[in] size Size of the buffer (in 16-bit samples).
*/
__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * p_buffer,
uint32_t size);
/**
* @brief Function for setting the SAADC result buffer pointer.
*
* @param[in] p_buffer Pointer to the result buffer.
*/
__STATIC_INLINE void nrf_saadc_buffer_pointer_set(nrf_saadc_value_t * p_buffer);
/**
* @brief Function for getting the SAADC result buffer pointer.
*
* @return Pointer to the result buffer.
*/
__STATIC_INLINE nrf_saadc_value_t * nrf_saadc_buffer_pointer_get(void);
/**
* @brief Function for getting the number of samples written to the result
* buffer since the previous START task.
*
* @returns Number of 16-bit samples written to the buffer.
*/
__STATIC_INLINE uint16_t nrf_saadc_amount_get(void);
/**
* @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);
/**
* @brief Function for getting the SAADC sample resolution.
*
* @return Sample resolution.
*/
__STATIC_INLINE nrf_saadc_resolution_t nrf_saadc_resolution_get(void);
/**
* @brief Function for configuring the oversampling feature.
*
* @param[in] oversample Oversampling mode.
*/
__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample);
/**
* @brief Function for getting the oversampling feature configuration.
*
* @return Oversampling configuration.
*/
__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void);
/**
* @brief Function for getting the sample count needed for one averaged result for a given
* oversampling configuration.
*
* @param[in] oversample Oversampling configuration.
*
* @return Sample count.
*/
__STATIC_INLINE uint32_t nrf_saadc_oversample_sample_count_get(nrf_saadc_oversample_t oversample);
/**
* @brief Function for enabling the continuous sampling.
*
* This function configures the SAADC internal timer to automatically take new samples at a fixed
* sample rate. Trigger the START task to begin continuous sampling. To stop the sampling, trigger
* the STOP task.
*
* @note The internal timer can only be used when a single input channel is enabled.
*
* @param[in] cc Capture and compare value. Sample rate is 16 MHz/cc. Valid CC range is
* from 80 to 2047.
*/
__STATIC_INLINE void nrf_saadc_continuous_mode_enable(uint16_t cc);
/**
* @brief Function for checking if the continuous sampling is enabled.
*
* @retval true The continuous sampling is enabled.
* @retval false The continuous sampling is disabled.
*/
__STATIC_INLINE bool nrf_saadc_continuous_mode_enable_check(void);
/**
* @brief Function for disabling the continuous sampling.
*
* New samples can still be acquired by manually triggering the SAMPLE task or by PPI.
*/
__STATIC_INLINE void nrf_saadc_continuous_mode_disable(void);
/**
* @brief Function for initializing the SAADC channel.
*
* @param[in] channel Channel number.
* @param[in] config Pointer to the channel configuration structure.
*/
__STATIC_INLINE void nrf_saadc_channel_init(uint8_t channel,
nrf_saadc_channel_config_t const * const config);
/**
* @brief Function for configuring the burst mode for the specified channel.
*
* @param[in] channel Channel number.
* @param[in] burst Burst mode setting.
*/
__STATIC_INLINE void nrf_saadc_burst_set(uint8_t channel,
nrf_saadc_burst_t burst);
/**
* @brief Function for getting the minimum value of the conversion result.
*
* The minimum value of the conversion result depends on the configured resolution.
*
* @param[in] resolution Bit resolution.
*
* @return Minimum value of the conversion result.
*/
__STATIC_INLINE nrf_saadc_value_t nrf_saadc_value_min_get(nrf_saadc_resolution_t resolution);
/**
* @brief Function for getting the maximum value of the conversion result.
*
* The maximum value of the conversion result depends on the configured resolution.
*
* @param[in] resolution Bit resolution.
*
* @return Maximum value of the conversion result.
*/
__STATIC_INLINE nrf_saadc_value_t nrf_saadc_value_max_get(nrf_saadc_resolution_t resolution);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t task)
{
*((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t task)
{
return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)task);
}
__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)event);
}
__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t event)
{
*((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE uint32_t nrf_saadc_event_address_get(nrf_saadc_event_t event)
{
return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)event);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_saadc_subscribe_set(nrf_saadc_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | SAADC_SUBSCRIBE_START_EN_Msk);
}
__STATIC_INLINE void nrf_saadc_subscribe_clear(nrf_saadc_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_saadc_publish_set(nrf_saadc_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | SAADC_PUBLISH_STARTED_EN_Msk);
}
__STATIC_INLINE void nrf_saadc_publish_clear(nrf_saadc_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) NRF_SAADC + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel,
nrf_saadc_limit_t limit_type)
{
NRFX_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;
}
}
__STATIC_INLINE nrf_saadc_event_t nrf_saadc_limit_event_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 );
}
}
__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;
}
__STATIC_INLINE void nrf_saadc_channel_pos_input_set(uint8_t channel,
nrf_saadc_input_t pselp)
{
NRF_SAADC->CH[channel].PSELP = pselp;
}
__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));
}
__STATIC_INLINE void nrf_saadc_int_set(uint32_t mask)
{
NRF_SAADC->INTEN = mask;
}
__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask)
{
NRF_SAADC->INTENSET = saadc_int_mask;
}
__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask)
{
return (bool)(NRF_SAADC->INTENSET & saadc_int_mask);
}
__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask)
{
NRF_SAADC->INTENCLR = saadc_int_mask;
}
__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type)
{
NRFX_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);
}
__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;
}
__STATIC_INLINE void nrf_saadc_enable(void)
{
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_saadc_disable(void)
{
NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE bool nrf_saadc_enable_check(void)
{
//simplified for performance
return NRF_SAADC->ENABLE;
}
__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * p_buffer,
uint32_t size)
{
NRF_SAADC->RESULT.PTR = (uint32_t)p_buffer;
NRF_SAADC->RESULT.MAXCNT = size;
}
__STATIC_INLINE void nrf_saadc_buffer_pointer_set(nrf_saadc_value_t * p_buffer)
{
NRF_SAADC->RESULT.PTR = (uint32_t)p_buffer;
}
__STATIC_INLINE nrf_saadc_value_t * nrf_saadc_buffer_pointer_get(void)
{
return (nrf_saadc_value_t *)NRF_SAADC->RESULT.PTR;
}
__STATIC_INLINE uint16_t nrf_saadc_amount_get(void)
{
return NRF_SAADC->RESULT.AMOUNT;
}
__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution)
{
NRF_SAADC->RESOLUTION = resolution;
}
__STATIC_INLINE nrf_saadc_resolution_t nrf_saadc_resolution_get(void)
{
return (nrf_saadc_resolution_t)NRF_SAADC->RESOLUTION;
}
__STATIC_INLINE uint32_t nrf_saadc_oversample_sample_count_get(nrf_saadc_oversample_t oversample)
{
return (1 << (uint32_t)oversample);
}
__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample)
{
NRF_SAADC->OVERSAMPLE = oversample;
}
__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void)
{
return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE;
}
__STATIC_INLINE void nrf_saadc_continuous_mode_enable(uint16_t cc)
{
NRFX_ASSERT((cc >= 80) && (cc <= 2047));
NRF_SAADC->SAMPLERATE = (SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos)
| ((uint32_t)cc << SAADC_SAMPLERATE_CC_Pos);
}
__STATIC_INLINE bool nrf_saadc_continuous_mode_enable_check(void)
{
return (bool)((NRF_SAADC->SAMPLERATE & SAADC_SAMPLERATE_MODE_Msk)
== (SAADC_SAMPLERATE_MODE_Timers << SAADC_SAMPLERATE_MODE_Pos));
}
__STATIC_INLINE void nrf_saadc_continuous_mode_disable(void)
{
NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;
}
__STATIC_INLINE 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)
| ((config->burst << SAADC_CH_CONFIG_BURST_Pos) & SAADC_CH_CONFIG_BURST_Msk);
nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n);
}
__STATIC_INLINE void nrf_saadc_burst_set(uint8_t channel,
nrf_saadc_burst_t burst)
{
NRF_SAADC->CH[channel].CONFIG =
(NRF_SAADC->CH[channel].CONFIG & ~SAADC_CH_CONFIG_BURST_Msk) |
(burst << SAADC_CH_CONFIG_BURST_Pos);
}
__STATIC_INLINE nrf_saadc_value_t nrf_saadc_value_min_get(nrf_saadc_resolution_t resolution)
{
uint8_t res_bits = 0;
switch (resolution)
{
case NRF_SAADC_RESOLUTION_8BIT:
res_bits = 8;
break;
case NRF_SAADC_RESOLUTION_10BIT:
res_bits = 10;
break;
case NRF_SAADC_RESOLUTION_12BIT:
res_bits = 12;
break;
case NRF_SAADC_RESOLUTION_14BIT:
res_bits = 14;
break;
default:
NRFX_ASSERT(false);
}
return (nrf_saadc_value_t)(-(1 << res_bits));
}
__STATIC_INLINE nrf_saadc_value_t nrf_saadc_value_max_get(nrf_saadc_resolution_t resolution)
{
uint8_t res_bits = 0;
switch (resolution)
{
case NRF_SAADC_RESOLUTION_8BIT:
res_bits = 8;
break;
case NRF_SAADC_RESOLUTION_10BIT:
res_bits = 10;
break;
case NRF_SAADC_RESOLUTION_12BIT:
res_bits = 12;
break;
case NRF_SAADC_RESOLUTION_14BIT:
res_bits = 14;
break;
default:
NRFX_ASSERT(false);
}
return (nrf_saadc_value_t)((1 << res_bits) - 1);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SAADC_H_
+371
View File
@@ -0,0 +1,371 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_SPI_H__
#define NRF_SPI_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_spi_hal SPI HAL
* @{
* @ingroup nrf_spi
* @brief Hardware access layer for managing the SPI peripheral.
*/
/**
* @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
{
NRF_SPI_EVENT_READY = offsetof(NRF_SPI_Type, EVENTS_READY) ///< TXD byte sent and RXD byte received.
} nrf_spi_event_t;
/** @brief SPI interrupts. */
typedef enum
{
NRF_SPI_INT_READY_MASK = SPI_INTENSET_READY_Msk, ///< Interrupt on READY event.
NRF_SPI_ALL_INTS_MASK = SPI_INTENSET_READY_Msk ///< All SPI interrupts.
} 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 the specified SPI event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be cleared.
*/
__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg,
nrf_spi_event_t event);
/**
* @brief Function for retrieving the state of the SPI event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg,
nrf_spi_event_t event);
/**
* @brief Function for getting the address of the specified SPI event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg,
nrf_spi_event_t event);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] spi_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg,
nrf_spi_int_mask_t spi_int);
/**
* @brief Function for enabling the SPI peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg);
/**
* @brief Function for disabling the SPI peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg);
/**
* @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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @param[in] data TX data to send.
*/
__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data);
/**
* @brief Function for reading data from the SPI receiver register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return RX data received.
*/
__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg);
/**
* @brief Function for setting the SPI master data rate.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] frequency SPI frequency.
*/
__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg,
nrf_spi_frequency_t frequency);
/**
* @brief Function for setting the SPI configuration.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] spi_mode SPI mode.
* @param[in] spi_bit_order SPI bit order.
*/
__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg,
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_reg,
nrf_spi_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg,
nrf_spi_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg,
nrf_spi_event_t event)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg,
nrf_spi_int_mask_t spi_int)
{
return (bool)(p_reg->INTENSET & spi_int);
}
__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg)
{
p_reg->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg)
{
p_reg->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin)
{
#if defined(SPI_PSEL_SCK_CONNECT_Pos)
p_reg->PSEL.SCK = sck_pin;
#else
p_reg->PSELSCK = sck_pin;
#endif
#if defined(SPI_PSEL_MOSI_CONNECT_Pos)
p_reg->PSEL.MOSI = mosi_pin;
#else
p_reg->PSELMOSI = mosi_pin;
#endif
#if defined(SPI_PSEL_MISO_CONNECT_Pos)
p_reg->PSEL.MISO = miso_pin;
#else
p_reg->PSELMISO = miso_pin;
#endif
}
__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data)
{
p_reg->TXD = data;
}
__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg)
{
return p_reg->RXD;
}
__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg,
nrf_spi_frequency_t frequency)
{
p_reg->FREQUENCY = frequency;
}
__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg,
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_reg->CONFIG = config;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SPI_H__
+801
View File
@@ -0,0 +1,801 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_SPIM_H__
#define NRF_SPIM_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_spim_hal SPIM HAL
* @{
* @ingroup nrf_spim
* @brief Hardware access layer for managing the SPIM peripheral.
*/
/**
* @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
#if defined(SPIM_DCXCNT_DCXCNT_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief This value specified in the DCX line configuration causes this line
* to be set low during whole transmission (all transmitted bytes are
* marked as command bytes). Any lower value causes the DCX line to be
* switched from low to high after this number of bytes is transmitted
* (all remaining bytes are marked as data bytes).
*/
#define NRF_SPIM_DCX_CNT_ALL_CMD 0xF
#endif
/** @brief Macro for checking if the hardware chip select function is available. */
#define NRF_SPIM_HW_CSN_PRESENT \
(NRFX_CHECK(SPIM0_FEATURE_HARDWARE_CSN_PRESENT) || \
NRFX_CHECK(SPIM1_FEATURE_HARDWARE_CSN_PRESENT) || \
NRFX_CHECK(SPIM2_FEATURE_HARDWARE_CSN_PRESENT) || \
NRFX_CHECK(SPIM3_FEATURE_HARDWARE_CSN_PRESENT))
/** @brief SPIM tasks. */
typedef enum
{
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.
} nrf_spim_task_t;
/** @brief SPIM events. */
typedef enum
{
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.
NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached.
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.
} nrf_spim_event_t;
/**
* @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_ALL_SHORTS_MASK = SPIM_SHORTS_END_START_Msk ///< All SPIM shortcuts.
} nrf_spim_short_mask_t;
/** @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.
NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event.
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_ALL_INTS_MASK = SPIM_INTENSET_STOPPED_Msk |
SPIM_INTENSET_ENDRX_Msk |
SPIM_INTENSET_END_Msk |
SPIM_INTENSET_ENDTX_Msk |
SPIM_INTENSET_STARTED_Msk ///< All SPIM interrupts.
} 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.
#if defined(SPIM_FREQUENCY_FREQUENCY_M16) || defined(__NRFX_DOXYGEN__)
NRF_SPIM_FREQ_16M = SPIM_FREQUENCY_FREQUENCY_M16, ///< 16 Mbps.
#endif
#if defined(SPIM_FREQUENCY_FREQUENCY_M32) || defined(__NRFX_DOXYGEN__)
NRF_SPIM_FREQ_32M = SPIM_FREQUENCY_FREQUENCY_M32 ///< 32 Mbps.
#endif
} 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;
#if (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
/** @brief SPI CSN pin polarity. */
typedef enum
{
NRF_SPIM_CSN_POL_LOW = SPIM_CSNPOL_CSNPOL_LOW, ///< Active low (idle state high).
NRF_SPIM_CSN_POL_HIGH = SPIM_CSNPOL_CSNPOL_HIGH ///< Active high (idle state low).
} nrf_spim_csn_pol_t;
#endif // (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for activating the specified SPIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task);
/**
* @brief Function for getting the address of the specified SPIM task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task The specified task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task);
/**
* @brief Function for clearing the specified SPIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be cleared.
*/
__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event);
/**
* @brief Function for retrieving the state of the SPIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event);
/**
* @brief Function for getting the address of the specified SPIM event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event);
/**
* @brief Function for enabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for getting the shortcut setting.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Current shortcut configuration.
*/
__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] spim_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg,
nrf_spim_int_mask_t spim_int);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* SPIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_spim_subscribe_set(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* SPIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* SPIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_spim_publish_set(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* SPIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_spim_publish_clear(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for enabling the SPIM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg);
/**
* @brief Function for disabling the SPIM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg);
/**
* @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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin);
#if (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for configuring the SPIM hardware CSN pin.
*
* If this signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] pin CSN pin number.
* @param[in] polarity CSN pin polarity.
* @param[in] duration Minimum duration between the edge of CSN and the edge of SCK
* and minimum duration of CSN must stay unselected between transactions.
* The value is specified in number of 64 MHz clock cycles (15.625 ns).
*/
__STATIC_INLINE void nrf_spim_csn_configure(NRF_SPIM_Type * p_reg,
uint32_t pin,
nrf_spim_csn_pol_t polarity,
uint32_t duration);
#endif // (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
#if defined(SPIM_PSELDCX_CONNECT_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for configuring the SPIM DCX pin.
*
* If this signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
* value instead of its pin number.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] dcx_pin DCX pin number.
*/
__STATIC_INLINE void nrf_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
uint32_t dcx_pin);
/**
* @brief Function for configuring the number of command bytes.
*
* Maximum value available for dividing the transmitted bytes into command
* bytes and data bytes is @ref NRF_SPIM_DCX_CNT_ALL_CMD - 1.
* The @ref NRF_SPIM_DCX_CNT_ALL_CMD value passed as the @c count parameter
* causes all transmitted bytes to be marked as command bytes.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] count Number of command bytes preceding the data bytes.
*/
__STATIC_INLINE void nrf_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,
uint32_t count);
#endif // defined(SPIM_PSELDCX_CONNECT_Msk) || defined(__NRFX_DOXYGEN__)
#if defined(SPIM_IFTIMING_RXDELAY_RXDELAY_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for configuring the extended SPIM interface.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param rxdelay Sample delay for input serial data on MISO,
* specified in 64 MHz clock cycles (15.625 ns) from the sampling edge of SCK.
*/
__STATIC_INLINE void nrf_spim_iftiming_set(NRF_SPIM_Type * p_reg,
uint32_t rxdelay);
#endif // defined(SPIM_IFTIMING_RXDELAY_RXDELAY_Msk) || defined(__NRFX_DOXYGEN__)
#if defined(SPIM_STALLSTAT_RX_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for clearing stall status for RX EasyDMA RAM accesses.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg);
/**
* @brief Function for getting stall status for RX EasyDMA RAM accesses.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Stall status of RX EasyDMA RAM accesses.
*/
__STATIC_INLINE bool nrf_spim_stallstat_rx_get(NRF_SPIM_Type * p_reg);
#endif // defined(SPIM_STALLSTAT_RX_Msk) || defined(__NRFX_DOXYGEN__)
#if defined(SPIM_STALLSTAT_TX_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for clearing stall status for TX EasyDMA RAM accesses.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg);
/**
* @brief Function for getting stall status for TX EasyDMA RAM accesses.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return Stall status of TX EasyDMA RAM accesses.
*/
__STATIC_INLINE bool nrf_spim_stallstat_tx_get(NRF_SPIM_Type * p_reg);
#endif // defined(SPIM_STALLSTAT_TX_Msk) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the SPI master data rate.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] frequency SPI frequency.
*/
__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg,
nrf_spim_frequency_t frequency);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t const * p_buffer,
size_t length);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t * p_buffer,
size_t length);
/**
* @brief Function for setting the SPI configuration.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] spi_mode SPI mode.
* @param[in] spi_bit_order SPI bit order.
*/
__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t orc);
/**
* @brief Function for enabling the TX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg);
/**
* @brief Function for disabling the TX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg);
/**
* @brief Function for enabling the RX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg);
/**
* @brief Function for disabling the RX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event)
{
return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg)
{
return p_reg->SHORTS;
}
__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg,
nrf_spim_int_mask_t spim_int)
{
return (bool)(p_reg->INTENSET & spim_int);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_spim_subscribe_set(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | SPIM_SUBSCRIBE_START_EN_Msk);
}
__STATIC_INLINE void nrf_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
nrf_spim_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_spim_publish_set(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | SPIM_PUBLISH_STARTED_EN_Msk);
}
__STATIC_INLINE void nrf_spim_publish_clear(NRF_SPIM_Type * p_reg,
nrf_spim_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg)
{
p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg)
{
p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg,
uint32_t sck_pin,
uint32_t mosi_pin,
uint32_t miso_pin)
{
p_reg->PSEL.SCK = sck_pin;
p_reg->PSEL.MOSI = mosi_pin;
p_reg->PSEL.MISO = miso_pin;
}
#if (NRF_SPIM_HW_CSN_PRESENT)
__STATIC_INLINE void nrf_spim_csn_configure(NRF_SPIM_Type * p_reg,
uint32_t pin,
nrf_spim_csn_pol_t polarity,
uint32_t duration)
{
p_reg->PSEL.CSN = pin;
p_reg->CSNPOL = polarity;
p_reg->IFTIMING.CSNDUR = duration;
}
#endif // defined(NRF_SPIM_HW_CSN_PRESENT)
#if defined(SPIM_PSELDCX_CONNECT_Msk)
__STATIC_INLINE void nrf_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
uint32_t dcx_pin)
{
p_reg->PSELDCX = dcx_pin;
}
__STATIC_INLINE void nrf_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,
uint32_t dcx_cnt)
{
p_reg->DCXCNT = dcx_cnt;
}
#endif // defined(SPIM_PSELDCX_CONNECT_Msk)
#if defined(SPIM_IFTIMING_RXDELAY_RXDELAY_Msk)
__STATIC_INLINE void nrf_spim_iftiming_set(NRF_SPIM_Type * p_reg,
uint32_t rxdelay)
{
p_reg->IFTIMING.RXDELAY = rxdelay;
}
#endif // defined(SPIM_IFTIMING_RXDELAY_RXDELAY_Msk)
#if defined(SPIM_STALLSTAT_RX_Msk)
__STATIC_INLINE void nrf_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)
{
p_reg->STALLSTAT &= ~(SPIM_STALLSTAT_RX_Msk);
}
__STATIC_INLINE bool nrf_spim_stallstat_rx_get(NRF_SPIM_Type * p_reg)
{
return (p_reg->STALLSTAT & SPIM_STALLSTAT_RX_Msk) != 0;
}
#endif // defined(SPIM_STALLSTAT_RX_Msk)
#if defined(SPIM_STALLSTAT_TX_Msk)
__STATIC_INLINE void nrf_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)
{
p_reg->STALLSTAT &= ~(SPIM_STALLSTAT_TX_Msk);
}
__STATIC_INLINE bool nrf_spim_stallstat_tx_get(NRF_SPIM_Type * p_reg)
{
return (p_reg->STALLSTAT & SPIM_STALLSTAT_TX_Msk) != 0;
}
#endif // defined(SPIM_STALLSTAT_TX_Msk)
__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg,
nrf_spim_frequency_t frequency)
{
p_reg->FREQUENCY = (uint32_t)frequency;
}
__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
uint8_t const * p_buffer,
size_t length)
{
p_reg->TXD.PTR = (uint32_t)p_buffer;
p_reg->TXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
uint8_t * p_buffer,
size_t length)
{
p_reg->RXD.PTR = (uint32_t)p_buffer;
p_reg->RXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg,
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_reg->CONFIG = config;
}
__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg,
uint8_t orc)
{
p_reg->ORC = orc;
}
__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg)
{
p_reg->TXD.LIST = 1;
}
__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg)
{
p_reg->TXD.LIST = 0;
}
__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg)
{
p_reg->RXD.LIST = 1;
}
__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg)
{
p_reg->RXD.LIST = 0;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SPIM_H__
+450
View File
@@ -0,0 +1,450 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_SPU_H__
#define NRF_SPU_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_spu_hal SPU HAL
* @{
* @ingroup nrf_spu
* @brief Hardware access layer for managing the System Protection Unit (SPU) peripheral.
*/
/** @brief SPU events. */
typedef enum
{
NRF_SPU_EVENT_RAMACCERR = offsetof(NRF_SPU_Type, EVENTS_RAMACCERR), ///< A security violation has been detected for the RAM memory space.
NRF_SPU_EVENT_FLASHACCERR = offsetof(NRF_SPU_Type, EVENTS_FLASHACCERR), ///< A security violation has been detected for the Flash memory space.
NRF_SPU_EVENT_PERIPHACCERR = offsetof(NRF_SPU_Type, EVENTS_PERIPHACCERR) ///< A security violation has been detected on one or several peripherals.
} nrf_spu_event_t;
/** @brief SPU interrupts. */
typedef enum
{
NRF_SPU_INT_RAMACCERR_MASK = SPU_INTENSET_RAMACCERR_Msk, ///< Interrupt on RAMACCERR event.
NRF_SPU_INT_FLASHACCERR_MASK = SPU_INTENSET_FLASHACCERR_Msk, ///< Interrupt on FLASHACCERR event.
NRF_SPU_INT_PERIPHACCERR_MASK = SPU_INTENSET_PERIPHACCERR_Msk ///< Interrupt on PERIPHACCERR event.
} nrf_spu_int_mask_t;
/** @brief SPU Non-Secure Callable (NSC) region size. */
typedef enum
{
NRF_SPU_NSC_SIZE_DISABLED = 0, ///< Not defined as a non-secure callable region.
NRF_SPU_NSC_SIZE_32B = 1, ///< Non-Secure Callable region with a 32-byte size
NRF_SPU_NSC_SIZE_64B = 2, ///< Non-Secure Callable region with a 64-byte size
NRF_SPU_NSC_SIZE_128B = 3, ///< Non-Secure Callable region with a 128-byte size
NRF_SPU_NSC_SIZE_256B = 4, ///< Non-Secure Callable region with a 256-byte size
NRF_SPU_NSC_SIZE_512B = 5, ///< Non-Secure Callable region with a 512-byte size
NRF_SPU_NSC_SIZE_1024B = 6, ///< Non-Secure Callable region with a 1024-byte size
NRF_SPU_NSC_SIZE_2048B = 7, ///< Non-Secure Callable region with a 2048-byte size
NRF_SPU_NSC_SIZE_4096B = 8 ///< Non-Secure Callable region with a 4096-byte size
} nrf_spu_nsc_size_t;
/** @brief SPU memory region permissions. */
typedef enum
{
NRF_SPU_MEM_PERM_EXECUTE = SPU_FLASHREGION_PERM_EXECUTE_Msk, ///< Allow code execution from particular memory region.
NRF_SPU_MEM_PERM_WRITE = SPU_FLASHREGION_PERM_WRITE_Msk, ///< Allow write operation on particular memory region.
NRF_SPU_MEM_PERM_READ = SPU_FLASHREGION_PERM_READ_Msk ///< Allow read operation from particular memory region.
} nrf_spu_mem_perm_t;
/**
* @brief Function for clearing a specific SPU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_spu_event_clear(NRF_SPU_Type * p_reg,
nrf_spu_event_t event);
/**
* @brief Function for retrieving the state of the SPU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_spu_event_check(NRF_SPU_Type const * p_reg,
nrf_spu_event_t event);
/**
* @brief Function for enabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be enabled.
*/
__STATIC_INLINE void nrf_spu_int_enable(NRF_SPU_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Interrupts to be disabled.
*/
__STATIC_INLINE void nrf_spu_int_disable(NRF_SPU_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] spu_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_spu_int_enable_check(NRF_SPU_Type const * p_reg,
uint32_t spu_int);
/**
* @brief Function for setting up publication configuration of a given SPU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to configure.
* @param[in] channel Channel to connect with published event.
*/
__STATIC_INLINE void nrf_spu_publish_set(NRF_SPU_Type * p_reg,
nrf_spu_event_t event,
uint32_t channel);
/**
* @brief Function for clearing publication configuration of a given SPU event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_spu_publish_clear(NRF_SPU_Type * p_reg,
nrf_spu_event_t event);
/**
* @brief Function for retrieving the capabilities of the current device.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @retval true ARM TrustZone support is available.
* @retval false ARM TrustZone support is not available.
*/
__STATIC_INLINE bool nrf_spu_tz_is_available(NRF_SPU_Type const * p_reg);
/**
* @brief Function for configuring the DPPI channels to be available in particular domains.
*
* Channels are configured as bitmask. Set one in bitmask to make channels available only in secure
* domain. Set zero to make it available in secure and non-secure domains.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] dppi_id DPPI peripheral id.
* @param[in] channels_mask Bitmask with channels configuration.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_dppi_config_set(NRF_SPU_Type * p_reg,
uint8_t dppi_id,
uint32_t channels_mask,
bool lock_conf);
/**
* @brief Function for configuring the GPIO pins to be available in particular domains.
*
* GPIO pins are configured as bitmask. Set one in bitmask to make particular pin available only
* in secure domain. Set zero to make it available in secure and non-secure domains.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] gpio_port Port number.
* @param[in] gpio_mask Bitmask with gpio configuration.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_gpio_config_set(NRF_SPU_Type * p_reg,
uint8_t gpio_port,
uint32_t gpio_mask,
bool lock_conf);
/**
* @brief Function for configuring non-secure callable flash region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] flash_nsc_id Non-secure callable flash region ID.
* @param[in] flash_nsc_size Non-secure callable flash region size.
* @param[in] region_number Flash region number.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_flashnsc_set(NRF_SPU_Type * p_reg,
uint8_t flash_nsc_id,
nrf_spu_nsc_size_t flash_nsc_size,
uint8_t region_number,
bool lock_conf);
/**
* @brief Function for configuring non-secure callable RAM region.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_nsc_id Non-secure callable RAM region ID.
* @param[in] ram_nsc_size Non-secure callable RAM region size.
* @param[in] region_number RAM region number.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_ramnsc_set(NRF_SPU_Type * p_reg,
uint8_t ram_nsc_id,
nrf_spu_nsc_size_t ram_nsc_size,
uint8_t region_number,
bool lock_conf);
/**
* @brief Function for configuring security for a particular flash region.
*
* Permissions parameter must be set by using the logical OR on the @ref nrf_spu_mem_perm_t values.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id Flash region index.
* @param[in] secure_attr Set region attribute to secure.
* @param[in] permissions Flash region permissions.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_flashregion_set(NRF_SPU_Type * p_reg,
uint8_t region_id,
bool secure_attr,
uint32_t permissions,
bool lock_conf);
/**
* @brief Function for configuring security for the RAM region.
*
* Permissions parameter must be set by using the logical OR on the @ref nrf_spu_mem_perm_t values.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] region_id RAM region index.
* @param[in] secure_attr Set region attribute to secure.
* @param[in] permissions RAM region permissions.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_ramregion_set(NRF_SPU_Type * p_reg,
uint8_t region_id,
bool secure_attr,
uint32_t permissions,
bool lock_conf);
/**
* @brief Function for configuring access permissions of the peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] peripheral_id ID number of a particular peripheral.
* @param[in] secure_attr Peripheral registers accessible only from secure domain.
* @param[in] secure_dma DMA transfers possible only from RAM memory in secure domain.
* @param[in] lock_conf Lock configuration until next SoC reset.
*/
__STATIC_INLINE void nrf_spu_peripheral_set(NRF_SPU_Type * p_reg,
uint32_t peripheral_id,
bool secure_attr,
bool secure_dma,
bool lock_conf);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_spu_event_clear(NRF_SPU_Type * p_reg,
nrf_spu_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
}
__STATIC_INLINE bool nrf_spu_event_check(NRF_SPU_Type const * p_reg,
nrf_spu_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_spu_int_enable(NRF_SPU_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_spu_int_disable(NRF_SPU_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_spu_int_enable_check(NRF_SPU_Type const * p_reg,
uint32_t spu_int)
{
return (bool)(p_reg->INTENSET & spu_int);
}
__STATIC_INLINE void nrf_spu_publish_set(NRF_SPU_Type * p_reg,
nrf_spu_event_t event,
uint32_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
(channel | (SPU_PUBLISH_RAMACCERR_EN_Msk));
}
__STATIC_INLINE void nrf_spu_publish_clear(NRF_SPU_Type * p_reg,
nrf_spu_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
__STATIC_INLINE bool nrf_spu_tz_is_available(NRF_SPU_Type const * p_reg)
{
return (p_reg->CAP & SPU_CAP_TZM_Msk ? true : false);
}
__STATIC_INLINE void nrf_spu_dppi_config_set(NRF_SPU_Type * p_reg,
uint8_t dppi_id,
uint32_t channels_mask,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->DPPI[dppi_id].LOCK & SPU_DPPI_LOCK_LOCK_Msk));
p_reg->DPPI[dppi_id].PERM = channels_mask;
if (lock_conf)
{
p_reg->DPPI[dppi_id].LOCK = (SPU_DPPI_LOCK_LOCK_Msk);
}
}
__STATIC_INLINE void nrf_spu_gpio_config_set(NRF_SPU_Type * p_reg,
uint8_t gpio_port,
uint32_t gpio_mask,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->GPIOPORT[gpio_port].LOCK & SPU_GPIOPORT_LOCK_LOCK_Msk));
p_reg->GPIOPORT[gpio_port].PERM = gpio_mask;
if (lock_conf)
{
p_reg->GPIOPORT[gpio_port].LOCK = (SPU_GPIOPORT_LOCK_LOCK_Msk);
}
}
__STATIC_INLINE void nrf_spu_flashnsc_set(NRF_SPU_Type * p_reg,
uint8_t flash_nsc_id,
nrf_spu_nsc_size_t flash_nsc_size,
uint8_t region_number,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->FLASHNSC[flash_nsc_id].REGION & SPU_FLASHNSC_REGION_LOCK_Msk));
NRFX_ASSERT(!(p_reg->FLASHNSC[flash_nsc_id].SIZE & SPU_FLASHNSC_SIZE_LOCK_Msk));
p_reg->FLASHNSC[flash_nsc_id].REGION = (uint32_t)region_number |
(lock_conf ? SPU_FLASHNSC_REGION_LOCK_Msk : 0);
p_reg->FLASHNSC[flash_nsc_id].SIZE = (uint32_t)flash_nsc_size |
(lock_conf ? SPU_FLASHNSC_SIZE_LOCK_Msk : 0);
}
__STATIC_INLINE void nrf_spu_ramnsc_set(NRF_SPU_Type * p_reg,
uint8_t ram_nsc_id,
nrf_spu_nsc_size_t ram_nsc_size,
uint8_t region_number,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->RAMNSC[ram_nsc_id].REGION & SPU_RAMNSC_REGION_LOCK_Msk));
NRFX_ASSERT(!(p_reg->RAMNSC[ram_nsc_id].SIZE & SPU_RAMNSC_SIZE_LOCK_Msk));
p_reg->RAMNSC[ram_nsc_id].REGION = (uint32_t)region_number |
(lock_conf ? SPU_RAMNSC_REGION_LOCK_Msk : 0);
p_reg->RAMNSC[ram_nsc_id].SIZE = (uint32_t)ram_nsc_size |
(lock_conf ? SPU_RAMNSC_SIZE_LOCK_Msk : 0);
}
__STATIC_INLINE void nrf_spu_flashregion_set(NRF_SPU_Type * p_reg,
uint8_t region_id,
bool secure_attr,
uint32_t permissions,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->FLASHREGION[region_id].PERM & SPU_FLASHREGION_PERM_LOCK_Msk));
p_reg->FLASHREGION[region_id].PERM = permissions |
(secure_attr ? SPU_FLASHREGION_PERM_SECATTR_Msk : 0) |
(lock_conf ? SPU_FLASHREGION_PERM_LOCK_Msk : 0);
}
__STATIC_INLINE void nrf_spu_ramregion_set(NRF_SPU_Type * p_reg,
uint8_t region_id,
bool secure_attr,
uint32_t permissions,
bool lock_conf)
{
NRFX_ASSERT(!(p_reg->RAMREGION[region_id].PERM & SPU_RAMREGION_PERM_LOCK_Msk));
p_reg->RAMREGION[region_id].PERM = permissions |
(secure_attr ? SPU_RAMREGION_PERM_SECATTR_Msk : 0) |
(lock_conf ? SPU_RAMREGION_PERM_LOCK_Msk : 0);
}
__STATIC_INLINE void nrf_spu_peripheral_set(NRF_SPU_Type * p_reg,
uint32_t peripheral_id,
bool secure_attr,
bool secure_dma,
bool lock_conf)
{
NRFX_ASSERT(p_reg->PERIPHID[peripheral_id].PERM & SPU_PERIPHID_PERM_PRESENT_Msk);
NRFX_ASSERT(!(p_reg->PERIPHID[peripheral_id].PERM & SPU_PERIPHID_PERM_LOCK_Msk));
p_reg->PERIPHID[peripheral_id].PERM =
(secure_attr ? SPU_PERIPHID_PERM_SECATTR_Msk : 0) |
(secure_dma ? SPU_PERIPHID_PERM_DMASEC_Msk : 0) |
(lock_conf ? SPU_PERIPHID_PERM_LOCK_Msk : 0);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_SPU_H__
+720
View File
@@ -0,0 +1,720 @@
/**
* Copyright (c) 2014 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_TIMER_H__
#define NRF_TIMER_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_timer_hal TIMER HAL
* @{
* @ingroup nrf_timer
* @brief Hardware access layer for managing the TIMER peripheral.
*/
/**
* @brief Macro for getting the maximum bit resolution of the specified timer instance.
*
* @param[in] id Index of the specified timer instance.
*
* @retval Maximum bit resolution of the specified timer instance.
*/
#define TIMER_MAX_SIZE(id) NRFX_CONCAT_3(TIMER, id, _MAX_SIZE)
/**
* @brief Macro for validating the correctness of the bit width resolution setting.
*
* @param[in] id Index of the specified timer instance.
* @param[in] bit_width Bit width resolution value to be checked.
*
* @retval true Timer instance supports the specified bit width resolution value.
* @retval false Timer instance does not support the specified bit width resolution value.
*/
#define TIMER_BIT_WIDTH_MAX(id, bit_width) \
(TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \
(TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) : \
(TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) || \
(bit_width == NRF_TIMER_BIT_WIDTH_24) : \
(TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \
(bit_width == NRF_TIMER_BIT_WIDTH_16) || \
(bit_width == NRF_TIMER_BIT_WIDTH_24) || \
(bit_width == NRF_TIMER_BIT_WIDTH_32) : \
false))))
/**
* @brief Macro for checking correctness of bit width configuration for the specified timer.
*
* @param[in] p_reg Timer instance register.
* @param[in] bit_width Bit width resolution value to be checked.
*
* @retval true Timer instance supports the specified bit width resolution value.
* @retval false Timer instance does not support the specified bit width resolution value.
*/
#if (TIMER_COUNT == 3) || defined(__NRFX_DOXYGEN__)
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \
|| ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \
|| ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)))
#elif (TIMER_COUNT == 4)
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \
|| ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \
|| ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) \
|| ((p_reg == NRF_TIMER3) && TIMER_BIT_WIDTH_MAX(3, bit_width)))
#elif (TIMER_COUNT == 5)
#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \
((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \
|| ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \
|| ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) \
|| ((p_reg == NRF_TIMER3) && TIMER_BIT_WIDTH_MAX(3, bit_width)) \
|| ((p_reg == NRF_TIMER4) && TIMER_BIT_WIDTH_MAX(4, bit_width)))
#else
#error "Not supported timer count"
#endif
/**
* @brief Macro for getting the number of capture/compare channels available
* in a given timer instance.
*
* @param[in] id Index of the specified timer instance.
*/
#define NRF_TIMER_CC_CHANNEL_COUNT(id) NRFX_CONCAT_3(TIMER, id, _CC_NUM)
/** @brief Timer tasks. */
typedef enum
{
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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5.
#endif
} nrf_timer_task_t;
/** @brief Timer events. */
typedef enum
{
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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5.
#endif
} 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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
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.
#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__NRFX_DOXYGEN__)
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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
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.
#if defined(TIMER_INTENSET_COMPARE4_Msk) || defined(__NRFX_DOXYGEN__)
NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4.
#endif
#if defined(TIMER_INTENSET_COMPARE5_Msk) || defined(__NRFX_DOXYGEN__)
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 the specified timer task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task);
/**
* @brief Function for getting the address of the specified timer task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task The specified task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task);
/**
* @brief Function for clearing the specified timer event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for retrieving the state of the TIMER event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for getting the address of the specified timer event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
/**
* @brief Function for enabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
uint32_t mask);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] timer_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
uint32_t timer_int);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* TIMER task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* TIMER task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* TIMER event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_timer_publish_set(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* TIMER event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_timer_publish_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the timer mode.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mode Timer mode.
*/
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
nrf_timer_mode_t mode);
/**
* @brief Function for retrieving the timer mode.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Timer mode.
*/
__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for setting the timer bit width.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] bit_width Timer bit width.
*/
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
nrf_timer_bit_width_t bit_width);
/**
* @brief Function for retrieving the timer bit width.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Timer bit width.
*/
__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for setting the timer frequency.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] frequency Timer frequency.
*/
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
nrf_timer_frequency_t frequency);
/**
* @brief Function for retrieving the timer frequency.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Timer frequency.
*/
__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg);
/**
* @brief Function for writing the capture/compare register for the specified channel.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] cc_channel The specified 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_reg,
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_reg Pointer to the structure of registers of the peripheral.
* @param[in] cc_channel The specified capture/compare channel.
*
* @return Value from the specified capture/compare register.
*/
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel);
/**
* @brief Function for getting the specified 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 the specified 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 the specified 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_reg,
nrf_timer_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg,
uint32_t timer_int)
{
return (bool)(p_reg->INTENSET & timer_int);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | TIMER_SUBSCRIBE_START_EN_Msk);
}
__STATIC_INLINE void nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,
nrf_timer_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_timer_publish_set(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | TIMER_PUBLISH_COMPARE_EN_Msk);
}
__STATIC_INLINE void nrf_timer_publish_clear(NRF_TIMER_Type * p_reg,
nrf_timer_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg,
nrf_timer_mode_t mode)
{
p_reg->MODE = (p_reg->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_reg)
{
return (nrf_timer_mode_t)(p_reg->MODE);
}
__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg,
nrf_timer_bit_width_t bit_width)
{
p_reg->BITMODE = (p_reg->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_reg)
{
return (nrf_timer_bit_width_t)(p_reg->BITMODE);
}
__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg,
nrf_timer_frequency_t frequency)
{
p_reg->PRESCALER = (p_reg->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_reg)
{
return (nrf_timer_frequency_t)(p_reg->PRESCALER);
}
__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel,
uint32_t cc_value)
{
p_reg->CC[cc_channel] = cc_value;
}
__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg,
nrf_timer_cc_channel_t cc_channel)
{
return (uint32_t)p_reg->CC[cc_channel];
}
__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel)
{
return (nrf_timer_task_t)NRFX_OFFSETOF(NRF_TIMER_Type, TASKS_CAPTURE[channel]);
}
__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel)
{
return (nrf_timer_event_t)NRFX_OFFSETOF(NRF_TIMER_Type, EVENTS_COMPARE[channel]);
}
__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;
uint64_t ticks = ((time_us * 16ULL) >> prescaler);
NRFX_ASSERT(ticks <= UINT32_MAX);
return (uint32_t)ticks;
}
__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;
uint64_t ticks = ((time_ms * 16000ULL) >> prescaler);
NRFX_ASSERT(ticks <= UINT32_MAX);
return (uint32_t)ticks;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_TIMER_H__
+476
View File
@@ -0,0 +1,476 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_TWI_H__
#define NRF_TWI_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_twi_hal TWI HAL
* @{
* @ingroup nrf_twi
* @brief Hardware access layer for managing the TWI peripheral.
*/
/** @brief TWI tasks. */
typedef enum
{
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.
} nrf_twi_task_t;
/** @brief TWI events. */
typedef enum
{
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.
} 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_ALL_SHORTS_MASK = TWI_SHORTS_BB_SUSPEND_Msk |
TWI_SHORTS_BB_STOP_Msk ///< All TWI shortcuts.
} 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_ALL_INTS_MASK = TWI_INTENSET_STOPPED_Msk |
TWI_INTENSET_RXDREADY_Msk |
TWI_INTENSET_TXDSENT_Msk |
TWI_INTENSET_ERROR_Msk |
TWI_INTENSET_BB_Msk |
TWI_INTENSET_SUSPENDED_Msk ///< All TWI interrupts.
} 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 the specified TWI task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
nrf_twi_task_t task);
/**
* @brief Function for getting the address of the specified TWI task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task The specified task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
nrf_twi_task_t task);
/**
* @brief Function for clearing the specified TWI event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg,
nrf_twi_event_t event);
/**
* @brief Function for retrieving the state of the TWI event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg,
nrf_twi_event_t event);
/**
* @brief Function for getting the address of the specified TWI event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg,
nrf_twi_event_t event);
/**
* @brief Function for enabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] twi_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
nrf_twi_int_mask_t twi_int);
/**
* @brief Function for enabling the TWI peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg);
/**
* @brief Function for disabling the TWI peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg);
/**
* @brief Function for configuring TWI pins.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint32_t scl_pin,
uint32_t sda_pin);
/**
* @brief Function for retrieving the SCL pin number.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return SCL pin number.
*/
__STATIC_INLINE uint32_t nrf_twi_scl_pin_get(NRF_TWI_Type * p_reg);
/**
* @brief Function for retrieving the SDA pin number.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return SDA pin number.
*/
__STATIC_INLINE uint32_t nrf_twi_sda_pin_get(NRF_TWI_Type * p_reg);
/**
* @brief Function for setting the TWI master clock frequency.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] frequency TWI frequency.
*/
__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
nrf_twi_frequency_t frequency);
/**
* @brief Function for checking the TWI error source.
*
* The error flags are cleared after reading.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg);
/**
* @brief Function for setting the address to be used in TWI transfers.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] address Address to be used in transfers.
*/
__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address);
/**
* @brief Function for reading data received by TWI.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Received data.
*/
__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg);
/**
* @brief Function for writing data to be transmitted by TWI.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] data Data to be transmitted.
*/
__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data);
/**
* @brief Function for setting the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be set.
*/
__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
uint32_t mask);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg,
nrf_twi_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg,
nrf_twi_task_t task)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg,
nrf_twi_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg,
nrf_twi_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg,
nrf_twi_event_t event)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg,
nrf_twi_int_mask_t twi_int)
{
return (bool)(p_reg->INTENSET & twi_int);
}
__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg)
{
p_reg->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg)
{
p_reg->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg,
uint32_t scl_pin,
uint32_t sda_pin)
{
#if defined(TWI_PSEL_SCL_CONNECT_Pos)
p_reg->PSEL.SCL = scl_pin;
#else
p_reg->PSELSCL = scl_pin;
#endif
#if defined(TWI_PSEL_SDA_CONNECT_Pos)
p_reg->PSEL.SDA = sda_pin;
#else
p_reg->PSELSDA = sda_pin;
#endif
}
__STATIC_INLINE uint32_t nrf_twi_scl_pin_get(NRF_TWI_Type * p_reg)
{
#if defined(TWI_PSEL_SCL_CONNECT_Pos)
return p_reg->PSEL.SCL;
#else
return p_reg->PSELSCL;
#endif
}
__STATIC_INLINE uint32_t nrf_twi_sda_pin_get(NRF_TWI_Type * p_reg)
{
#if defined(TWI_PSEL_SDA_CONNECT_Pos)
return p_reg->PSEL.SDA;
#else
return p_reg->PSELSDA;
#endif
}
__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg,
nrf_twi_frequency_t frequency)
{
p_reg->FREQUENCY = frequency;
}
__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg)
{
uint32_t error_source = p_reg->ERRORSRC;
// [error flags are cleared by writing '1' on their position]
p_reg->ERRORSRC = error_source;
return error_source;
}
__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address)
{
p_reg->ADDRESS = address;
}
__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg)
{
return (uint8_t)p_reg->RXD;
}
__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data)
{
p_reg->TXD = data;
}
__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS = mask;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_TWI_H__
+619
View File
@@ -0,0 +1,619 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_TWIM_H__
#define NRF_TWIM_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_twim_hal TWIM HAL
* @{
* @ingroup nrf_twim
* @brief Hardware access layer for managing the TWIM peripheral.
*/
/** @brief TWIM tasks. */
typedef enum
{
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.
} nrf_twim_task_t;
/** @brief TWIM events. */
typedef enum
{
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.
} 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_ALL_SHORTS_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk |
TWIM_SHORTS_LASTTX_SUSPEND_Msk |
TWIM_SHORTS_LASTTX_STOP_Msk |
TWIM_SHORTS_LASTRX_STARTTX_Msk |
TWIM_SHORTS_LASTRX_STOP_Msk ///< All TWIM shortcuts.
} 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 = TWIM_INTENSET_SUSPENDED_Msk, ///< 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_ALL_INTS_MASK = TWIM_INTENSET_STOPPED_Msk |
TWIM_INTENSET_ERROR_Msk |
TWIM_INTENSET_SUSPENDED_Msk |
TWIM_INTENSET_RXSTARTED_Msk |
TWIM_INTENSET_TXSTARTED_Msk |
TWIM_INTENSET_LASTRX_Msk |
TWIM_INTENSET_LASTTX_Msk ///< All TWIM interrupts.
} 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_OVERRUN = TWIM_ERRORSRC_OVERRUN_Msk ///< Overrun error.
/**< A new byte was received before the previous byte was
* handled by peripheral. (previous data is lost). */
} nrf_twim_error_t;
/**
* @brief Function for activating the specified TWIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task to be activated.
*/
__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task);
/**
* @brief Function for getting the address of the specified TWIM task register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task The specified task.
*
* @return Address of the specified task register.
*/
__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task);
/**
* @brief Function for clearing the specified TWIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to clear.
*/
__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event);
/**
* @brief Function for retrieving the state of the TWIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event);
/**
* @brief Function for getting the address of the specified TWIM event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return Address of the specified event register.
*/
__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event);
/**
* @brief Function for enabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for enabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for checking the state of a given interrupt.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] twim_int Interrupt to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg,
nrf_twim_int_mask_t twim_int);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* TWIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_twim_subscribe_set(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* TWIM task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_twim_subscribe_clear(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* TWIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_twim_publish_set(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* TWIM event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_twim_publish_clear(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for enabling the TWIM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg);
/**
* @brief Function for disabling the TWIM peripheral.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg);
/**
* @brief Function for configuring TWI pins.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint32_t scl_pin,
uint32_t sda_pin);
/**
* @brief Function for setting the TWI master clock frequency.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] frequency TWI frequency.
*/
__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg,
nrf_twim_frequency_t frequency);
/**
* @brief Function for checking the TWI error source.
*
* The error flags are cleared after reading.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Mask with error source flags.
*/
__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg);
/**
* @brief Function for setting the address to be used in TWI transfers.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] address Address to be used in transfers.
*/
__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg,
uint8_t address);
/**
* @brief Function for setting the transmit buffer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t const * p_buffer,
size_t length);
/**
* @brief Function for setting the receive buffer.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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_reg,
uint8_t * p_buffer,
size_t length);
/**
* @brief Function for setting the specified shortcuts.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] mask Shortcuts to be set.
*/
__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
uint32_t mask);
/**
* @brief Function for getting the shortcut setting.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Current shortcut configuration.
*/
__STATIC_INLINE uint32_t nrf_twim_shorts_get(NRF_TWIM_Type const * p_reg);
/**
* @brief Function for getting the amount of transmitted bytes.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Amount of transmitted bytes.
*/
__STATIC_INLINE size_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg);
/**
* @brief Function for getting the amount of received bytes.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @return Amount of received bytes.
*/
__STATIC_INLINE size_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg);
/**
* @brief Function for enabling the TX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg);
/**
* @brief Function for disabling the TX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg);
/**
* @brief Function for enabling the RX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg);
/**
* @brief Function for disabling the RX list feature.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
}
__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task);
}
__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event)
{
*((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event)
{
return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event)
{
return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
}
__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg,
uint32_t mask)
{
p_reg->INTENCLR = mask;
}
__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg,
nrf_twim_int_mask_t twim_int)
{
return (bool)(p_reg->INTENSET & twim_int);
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_twim_subscribe_set(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | TWIM_SUBSCRIBE_STARTRX_EN_Msk);
}
__STATIC_INLINE void nrf_twim_subscribe_clear(NRF_TWIM_Type * p_reg,
nrf_twim_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_twim_publish_set(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | TWIM_PUBLISH_STOPPED_EN_Msk);
}
__STATIC_INLINE void nrf_twim_publish_clear(NRF_TWIM_Type * p_reg,
nrf_twim_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg)
{
p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg)
{
p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
}
__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg,
uint32_t scl_pin,
uint32_t sda_pin)
{
p_reg->PSEL.SCL = scl_pin;
p_reg->PSEL.SDA = sda_pin;
}
__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg,
nrf_twim_frequency_t frequency)
{
p_reg->FREQUENCY = frequency;
}
__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg)
{
uint32_t error_source = p_reg->ERRORSRC;
// [error flags are cleared by writing '1' on their position]
p_reg->ERRORSRC = error_source;
return error_source;
}
__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg,
uint8_t address)
{
p_reg->ADDRESS = address;
}
__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg,
uint8_t const * p_buffer,
size_t length)
{
p_reg->TXD.PTR = (uint32_t)p_buffer;
p_reg->TXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg,
uint8_t * p_buffer,
size_t length)
{
p_reg->RXD.PTR = (uint32_t)p_buffer;
p_reg->RXD.MAXCNT = length;
}
__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg,
uint32_t mask)
{
p_reg->SHORTS = mask;
}
__STATIC_INLINE size_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg)
{
return p_reg->TXD.AMOUNT;
}
__STATIC_INLINE uint32_t nrf_twim_shorts_get(NRF_TWIM_Type const * p_reg)
{
return p_reg->SHORTS;
}
__STATIC_INLINE size_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg)
{
return p_reg->RXD.AMOUNT;
}
__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg)
{
p_reg->TXD.LIST = 1;
}
__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg)
{
p_reg->TXD.LIST = 0;
}
__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg)
{
p_reg->RXD.LIST = 1;
}
__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg)
{
p_reg->RXD.LIST = 0;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_TWIM_H__
+511
View File
@@ -0,0 +1,511 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_UART_H__
#define NRF_UART_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_uart_hal UART HAL
* @{
* @ingroup nrf_uart
* @brief Hardware access layer for managing the UART peripheral.
*/
/** @brief Pin disconnected value. */
#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF
/** @brief UART tasks. */
typedef enum
{
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. */
} nrf_uart_task_t;
/** @brief UART events. */
typedef enum
{
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. */
} nrf_uart_event_t;
/** @brief UART interrupts. */
typedef enum
{
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. */
} nrf_uart_int_mask_t;
/** @brief Baudrates supported by UART. */
typedef enum
{
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_31250 = UART_BAUDRATE_BAUDRATE_Baud31250, /**< 31250 baud. */
NRF_UART_BAUDRATE_38400 = UART_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */
NRF_UART_BAUDRATE_56000 = UART_BAUDRATE_BAUDRATE_Baud56000, /**< 56000 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. */
} nrf_uart_baudrate_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;
/** @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;
/** @brief Types of UART flow control modes. */
typedef enum
{
NRF_UART_HWFC_DISABLED = UART_CONFIG_HWFC_Disabled, /**< Hardware flow control disabled. */
NRF_UART_HWFC_ENABLED = UART_CONFIG_HWFC_Enabled, /**< Hardware flow control enabled. */
} nrf_uart_hwfc_t;
/**
* @brief Function for clearing the specified UART event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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 retrieving the state of the UART event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event);
/**
* @brief Function for returning the address of the specified UART event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Desired event.
*
* @return Address of the 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 the specified interrupt.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of a given interrupt.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t mask);
/**
* @brief Function for getting error source mask. Function is clearing error source flags after reading.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg);
/**
* @brief Function for disabling UART.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg);
/**
* @brief Function for configuring TX/RX pins.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg);
/**
* @brief Function for getting TX pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return TX pin number.
*/
__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting RX pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return RX pin number.
*/
__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting RTS pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return RTS pin number.
*/
__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for getting CTS pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return CTS pin number.
*/
__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg);
/**
* @brief Function for configuring flow control pins.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg);
/**
* @brief Function for reading RX data.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @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 Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
* @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 the specified task register.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
* @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 baud rate.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param baudrate Baud rate.
*/
__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;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__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 mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t mask)
{
return (bool)(p_reg->INTENSET & mask);
}
__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = 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)
{
#if defined(UART_PSEL_RXD_CONNECT_Pos)
p_reg->PSEL.RXD = pselrxd;
#else
p_reg->PSELRXD = pselrxd;
#endif
#if defined(UART_PSEL_TXD_CONNECT_Pos)
p_reg->PSEL.TXD = pseltxd;
#else
p_reg->PSELTXD = pseltxd;
#endif
}
__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)
{
#if defined(UART_PSEL_TXD_CONNECT_Pos)
return p_reg->PSEL.TXD;
#else
return p_reg->PSELTXD;
#endif
}
__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg)
{
#if defined(UART_PSEL_RXD_CONNECT_Pos)
return p_reg->PSEL.RXD;
#else
return p_reg->PSELRXD;
#endif
}
__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg)
{
#if defined(UART_PSEL_RTS_CONNECT_Pos)
return p_reg->PSEL.RTS;
#else
return p_reg->PSELRTS;
#endif
}
__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg)
{
#if defined(UART_PSEL_RTS_CONNECT_Pos)
return p_reg->PSEL.CTS;
#else
return p_reg->PSELCTS;
#endif
}
__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts)
{
#if defined(UART_PSEL_RTS_CONNECT_Pos)
p_reg->PSEL.RTS = pselrts;
#else
p_reg->PSELRTS = pselrts;
#endif
#if defined(UART_PSEL_RTS_CONNECT_Pos)
p_reg->PSEL.CTS = pselcts;
#else
p_reg->PSELCTS = pselcts;
#endif
}
__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
/** @} */
#ifdef __cplusplus
}
#endif
#endif //NRF_UART_H__
+637
View File
@@ -0,0 +1,637 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_UARTE_H__
#define NRF_UARTE_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF
/**
* @defgroup nrf_uarte_hal UARTE HAL
* @{
* @ingroup nrf_uarte
* @brief Hardware access layer for managing the UARTE peripheral.
*/
/** @brief UARTE tasks. */
typedef enum
{
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.
} nrf_uarte_task_t;
/** @brief UARTE events. */
typedef enum
{
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_RXDRDY = offsetof(NRF_UARTE_Type, EVENTS_RXDRDY), ///< Data received in RXD (but potentially not yet transferred to Data RAM).
NRF_UARTE_EVENT_ENDRX = offsetof(NRF_UARTE_Type, EVENTS_ENDRX), ///< Receive buffer is filled up.
NRF_UARTE_EVENT_TXDRDY = offsetof(NRF_UARTE_Type, EVENTS_TXDRDY), ///< Data sent from TXD.
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.
} 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;
/** @brief UARTE interrupts. */
typedef enum
{
NRF_UARTE_INT_CTS_MASK = UARTE_INTENSET_CTS_Msk, ///< Interrupt on CTS event.
NRF_UARTE_INT_NCTS_MASK = UARTE_INTENSET_NCTS_Msk, ///< Interrupt on NCTS event.
NRF_UARTE_INT_RXDRDY_MASK = UARTE_INTENSET_RXDRDY_Msk, ///< Interrupt on RXDRDY event.
NRF_UARTE_INT_ENDRX_MASK = UARTE_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
NRF_UARTE_INT_TXDRDY_MASK = UARTE_INTENSET_TXDRDY_Msk, ///< Interrupt on TXDRDY 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;
/** @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_31250 = UARTE_BAUDRATE_BAUDRATE_Baud31250, ///< 31250 baud.
NRF_UARTE_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, ///< 38400 baud.
NRF_UARTE_BAUDRATE_56000 = UARTE_BAUDRATE_BAUDRATE_Baud56000, ///< 56000 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;
/** @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;
/** @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;
/** @brief Types of UARTE flow control modes. */
typedef enum
{
NRF_UARTE_HWFC_DISABLED = UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos, ///< Hardware flow control disabled.
NRF_UARTE_HWFC_ENABLED = UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos ///< Hardware flow control enabled.
} nrf_uarte_hwfc_t;
/**
* @brief Function for clearing the specified UARTE event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @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 retrieving the state of the UARTE event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event);
/**
* @brief Function for returning the address of the specified UARTE event register.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event The specified event.
*
* @return 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 Pointer to the structure of registers of the peripheral.
* @param mask Shortcuts to be enabled.
*/
__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t mask);
/**
* @brief Function for disabling UARTE shortcuts.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Shortcuts to be disabled.
*/
__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t mask);
/**
* @brief Function for enabling UARTE interrupts.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be enabled.
*/
__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t mask);
/**
* @brief Function for retrieving the state of the specified interrupt.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be checked.
*
* @retval true The interrupt is enabled.
* @retval false The interrupt is not enabled.
*/
__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t mask);
/**
* @brief Function for disabling the specified interrupts.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param mask Mask of interrupts to be disabled.
*/
__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t mask);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* UARTE task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_uarte_subscribe_set(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* UARTE task.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_uarte_subscribe_clear(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* UARTE event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_uarte_publish_set(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* UARTE event.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_uarte_publish_clear(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for getting error source mask. Function is clearing error source flags after reading.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg);
/**
* @brief Function for disabling UARTE.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg);
/**
* @brief Function for configuring TX/RX pins.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting TX pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return TX pin number.
*/
__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting RX pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return RX pin number.
*/
__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting RTS pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return RTS pin number.
*/
__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for getting CTS pin.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
*
* @return CTS pin number.
*/
__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg);
/**
* @brief Function for configuring flow control pins.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
*/
__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg);
/**
* @brief Function for starting an UARTE task.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 the specified task register.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @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 Pointer to the structure of registers of the peripheral.
* @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 baud rate.
*
* @param p_reg Pointer to the structure of registers of the peripheral.
* @param baudrate Baud rate.
*/
__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 Pointer to the structure of registers of the peripheral.
* @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,
size_t length);
/**
* @brief Function for getting number of bytes transmitted in the last transaction.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @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 Pointer to the structure of registers of the peripheral.
* @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,
size_t length);
/**
* @brief Function for getting number of bytes received in the last transaction.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
*
* @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;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
(void)dummy;
#endif
}
__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 mask)
{
p_reg->SHORTS |= mask;
}
__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t mask)
{
p_reg->SHORTS &= ~(mask);
}
__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t mask)
{
p_reg->INTENSET = mask;
}
__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t mask)
{
return (bool)(p_reg->INTENSET & mask);
}
__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t mask)
{
p_reg->INTENCLR = mask;
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_uarte_subscribe_set(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | UARTE_SUBSCRIBE_STARTRX_EN_Msk);
}
__STATIC_INLINE void nrf_uarte_subscribe_clear(NRF_UARTE_Type * p_reg,
nrf_uarte_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_uarte_publish_set(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | UARTE_PUBLISH_CTS_EN_Msk);
}
__STATIC_INLINE void nrf_uarte_publish_clear(NRF_UARTE_Type * p_reg,
nrf_uarte_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__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,
size_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,
size_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
/** @} */
#ifdef __cplusplus
}
#endif
#endif //NRF_UARTE_H__
+259
View File
@@ -0,0 +1,259 @@
/**
* Copyright (c) 2018 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_VMC_H__
#define NRF_VMC_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_vmc_hal VMC HAL
* @{
* @ingroup nrf_vmc
* @brief Hardware access layer for managing the Volatile Memory Controller (VMC) peripheral.
*/
/** @brief Power configuration bits for each section in particular RAM block. */
typedef enum
{
NRF_VMC_POWER_S0 = VMC_RAM_POWER_S0POWER_Msk, ///< Keep retention on RAM section S0 of the particular RAM block when RAM section is switched off.
NRF_VMC_POWER_S1 = VMC_RAM_POWER_S1POWER_Msk, ///< Keep retention on RAM section S1 of the particular RAM block when RAM section is switched off.
NRF_VMC_POWER_S2 = VMC_RAM_POWER_S2POWER_Msk, ///< Keep retention on RAM section S2 of the particular RAM block when RAM section is switched off.
NRF_VMC_POWER_S3 = VMC_RAM_POWER_S3POWER_Msk, ///< Keep retention on RAM section S3 of the particular RAM block when RAM section is switched off.
} nrf_vmc_power_t;
/** @brief Retention configuration bits for each section in particular RAM block. */
typedef enum
{
NRF_VMC_RETENTION_S0 = VMC_RAM_POWER_S0RETENTION_Msk, ///< Keep RAM section S0 of the particular RAM block on or off in System ON mode.
NRF_VMC_RETENTION_S1 = VMC_RAM_POWER_S1RETENTION_Msk, ///< Keep RAM section S1 of the particular RAM block on or off in System ON mode.
NRF_VMC_RETENTION_S2 = VMC_RAM_POWER_S2RETENTION_Msk, ///< Keep RAM section S2 of the particular RAM block on or off in System ON mode.
NRF_VMC_RETENTION_S3 = VMC_RAM_POWER_S3RETENTION_Msk, ///< Keep RAM section S3 of the particular RAM block on or off in System ON mode.
} nrf_vmc_retention_t;
/**
* @brief Function for setting power configuration for the particular RAM block.
*
* @note Overrides current configuration.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
* @param[in] power_mask Bitmask with sections configuration of particular RAM block.
* @ref nrf_vmc_power_t should be use to prepare this bitmask.
* @param[in] retention_mask Bitmask with sections configuration of particular RAM block.
* @ref nrf_vmc_retention_t should be use to prepare this bitmask.
*/
__STATIC_INLINE void nrf_vmc_ram_block_config(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
uint32_t power_mask,
uint32_t retention_mask);
/**
* @brief Function for clearing power configuration for the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
*/
__STATIC_INLINE void nrf_vmc_ram_block_clear(NRF_VMC_Type * p_reg, uint8_t ram_block_num);
/**
* @brief Function for setting power configuration for the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
* @param[in] sect_power Paricular section of the RAM block.
*/
__STATIC_INLINE void nrf_vmc_ram_block_power_set(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_power_t sect_power);
/**
* @brief Function for clearing power configuration for the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
* @param[in] sect_power Paricular section of the RAM block.
*/
__STATIC_INLINE void nrf_vmc_ram_block_power_clear(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_power_t sect_power);
/**
* @brief Function for getting power configuration of the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
*
* @return Bitmask with power configuration of sections of particular RAM block.
*/
__STATIC_INLINE uint32_t nrf_vmc_ram_block_power_mask_get(NRF_VMC_Type const * p_reg,
uint8_t ram_block_num);
/**
* @brief Function for setting retention configuration for the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
* @param[in] sect_retention Paricular section of the RAM block.
*/
__STATIC_INLINE void nrf_vmc_ram_block_retention_set(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_retention_t sect_retention);
/**
* @brief Function for clearing retention configuration for the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
* @param[in] sect_retention Paricular section of the RAM block.
*/
__STATIC_INLINE void nrf_vmc_ram_block_retention_clear(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_retention_t sect_retention);
/**
* @brief Function for getting retention configuration of the particular RAM block.
*
* @param[in] p_reg Pointer to the structure of registers of the peripheral.
* @param[in] ram_block_num RAM block number.
*
* @return Bitmask with retention configuration of sections of particular RAM block
*/
__STATIC_INLINE uint32_t nrf_vmc_ram_block_retention_mask_get(NRF_VMC_Type const * p_reg,
uint8_t ram_block_num);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_vmc_ram_block_config(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
uint32_t power_mask,
uint32_t retention_mask)
{
p_reg->RAM[ram_block_num].POWER =
(power_mask & (
VMC_RAM_POWER_S0POWER_Msk |
VMC_RAM_POWER_S1POWER_Msk |
VMC_RAM_POWER_S2POWER_Msk |
VMC_RAM_POWER_S3POWER_Msk)) |
(retention_mask & (
VMC_RAM_POWER_S0RETENTION_Msk |
VMC_RAM_POWER_S1RETENTION_Msk |
VMC_RAM_POWER_S2RETENTION_Msk |
VMC_RAM_POWER_S3RETENTION_Msk));
// Perform dummy read of the POWER register to ensure that configuration of sections was
// written to the VMC peripheral.
volatile uint32_t dummy = p_reg->RAM[ram_block_num].POWER;
(void)dummy;
}
__STATIC_INLINE void nrf_vmc_ram_block_clear(NRF_VMC_Type * p_reg, uint8_t ram_block_num)
{
p_reg->RAM[ram_block_num].POWER = 0;
}
__STATIC_INLINE void nrf_vmc_ram_block_power_set(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_power_t sect_power)
{
p_reg->RAM[ram_block_num].POWERSET = (uint32_t)sect_power;
// Perform dummy read of the POWERSET register to ensure that configuration of sections was
// written to the VMC peripheral.
volatile uint32_t dummy = p_reg->RAM[ram_block_num].POWERSET;
(void)dummy;
}
__STATIC_INLINE void nrf_vmc_ram_block_power_clear(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_power_t sect_power)
{
p_reg->RAM[ram_block_num].POWERCLR = (uint32_t)sect_power;
}
__STATIC_INLINE uint32_t nrf_vmc_ram_block_power_mask_get(NRF_VMC_Type const * p_reg,
uint8_t ram_block_num)
{
return p_reg->RAM[ram_block_num].POWER & (
VMC_RAM_POWER_S0POWER_Msk |
VMC_RAM_POWER_S1POWER_Msk |
VMC_RAM_POWER_S2POWER_Msk |
VMC_RAM_POWER_S3POWER_Msk);
}
__STATIC_INLINE void nrf_vmc_ram_block_retention_set(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_retention_t sect_retention)
{
p_reg->RAM[ram_block_num].POWERSET = (uint32_t)sect_retention;
// Perform dummy read of the POWERSET register to ensure that configuration of sections was
// written to the VMC peripheral.
volatile uint32_t dummy = p_reg->RAM[ram_block_num].POWERSET;
(void)dummy;
}
__STATIC_INLINE void nrf_vmc_ram_block_retention_clear(NRF_VMC_Type * p_reg,
uint8_t ram_block_num,
nrf_vmc_retention_t sect_retention)
{
p_reg->RAM[ram_block_num].POWERCLR = (uint32_t)sect_retention;
}
__STATIC_INLINE uint32_t nrf_vmc_ram_block_retention_mask_get(NRF_VMC_Type const * p_reg,
uint8_t ram_block_num)
{
return p_reg->RAM[ram_block_num].POWER & (
VMC_RAM_POWER_S0RETENTION_Msk |
VMC_RAM_POWER_S1RETENTION_Msk |
VMC_RAM_POWER_S2RETENTION_Msk |
VMC_RAM_POWER_S3RETENTION_Msk);
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_VMC_H__
+402
View File
@@ -0,0 +1,402 @@
/**
* Copyright (c) 2015 - 2021, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_WDT_H__
#define NRF_WDT_H__
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup nrf_wdt_hal WDT HAL
* @{
* @ingroup nrf_wdt
* @brief Hardware access layer for managing the Watchdog Timer (WDT) peripheral.
*/
/** @brief Number of WDT channels. */
#define NRF_WDT_CHANNEL_NUMBER 0x8UL
/** @brief WDT register reload value. */
#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value; should not be modified. */
/** @brief WDT tasks. */
typedef enum
{
NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
} nrf_wdt_task_t;
/** @brief WDT events. */
typedef enum
{
NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
} nrf_wdt_event_t;
/** @brief WDT behavior in the SLEEP or HALT CPU modes. */
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;
/** @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;
/** @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);
/**
* @brief Function for starting the WDT task.
*
* @param[in] task Task.
*/
__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task);
/**
* @brief Function for clearing the WDT event register.
*
* @param[in] event Event.
*/
__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event);
/**
* @brief Function for retrieving the state of the WDT event.
*
* @param[in] event Event to be checked.
*
* @retval true The event has been generated.
* @retval false The event has not been generated.
*/
__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event);
/**
* @brief Function for enabling the specified interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_wdt_int_enable(uint32_t 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);
/**
* @brief Function for disabling a specific interrupt.
*
* @param[in] int_mask Interrupt.
*/
__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask);
#if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @brief Function for setting the subscribe configuration for a given
* WDT task.
*
* @param[in] task Task for which to set the configuration.
* @param[in] channel Channel through which to subscribe events.
*/
__STATIC_INLINE void nrf_wdt_subscribe_set(nrf_wdt_task_t task,
uint8_t channel);
/**
* @brief Function for clearing the subscribe configuration for a given
* WDT task.
*
* @param[in] task Task for which to clear the configuration.
*/
__STATIC_INLINE void nrf_wdt_subscribe_clear(nrf_wdt_task_t task);
/**
* @brief Function for setting the publish configuration for a given
* WDT event.
*
* @param[in] event Event for which to set the configuration.
* @param[in] channel Channel through which to publish the event.
*/
__STATIC_INLINE void nrf_wdt_publish_set(nrf_wdt_event_t event,
uint8_t channel);
/**
* @brief Function for clearing the publish configuration for a given
* WDT event.
*
* @param[in] event Event for which to clear the configuration.
*/
__STATIC_INLINE void nrf_wdt_publish_clear(nrf_wdt_event_t event);
#endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
/**
* @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);
/**
* @brief Function for returning the address of a specific WDT event register.
*
* @param[in] event Event.
*
* @return Address of requested event register
*/
__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event);
/**
* @brief Function for retrieving the watchdog status.
*
* @retval true The watchdog is started.
* @retval false The watchdog is not started.
*/
__STATIC_INLINE bool nrf_wdt_started(void);
/**
* @brief Function for retrieving the watchdog reload request status.
*
* @param[in] rr_register Reload request register to be checked.
*
* @retval true Reload request is running.
* @retval false No reload requests are running.
*/
__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register);
/**
* @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);
/**
* @brief Function for retrieving the watchdog reload value.
*
* @return Reload value.
*/
__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void);
/**
* @brief Function for enabling a specific reload request register.
*
* @param[in] rr_register Reload request register to be enabled.
*/
__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register);
/**
* @brief Function for disabling a specific reload request register.
*
* @param[in] rr_register Reload request register to be disabled.
*/
__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register);
/**
* @brief Function for retrieving the status of a specific reload request register.
*
* @param[in] rr_register Reload request register to be checked.
*
* @retval true The reload request register is enabled.
* @retval false The reload request register is not enabled.
*/
__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t 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);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
{
NRF_WDT->CONFIG = behaviour;
}
__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
{
*((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)task)) = 0x01UL;
}
__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
{
*((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = 0x0UL;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event));
(void)dummy;
#endif
}
__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
{
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event));
}
__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
{
NRF_WDT->INTENSET = int_mask;
}
__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
{
return (bool)(NRF_WDT->INTENSET & int_mask);
}
__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
{
NRF_WDT->INTENCLR = int_mask;
}
#if defined(DPPI_PRESENT)
__STATIC_INLINE void nrf_wdt_subscribe_set(nrf_wdt_task_t task,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_WDT + (uint32_t) task + 0x80uL)) =
((uint32_t)channel | WDT_SUBSCRIBE_START_EN_Msk);
}
__STATIC_INLINE void nrf_wdt_subscribe_clear(nrf_wdt_task_t task)
{
*((volatile uint32_t *) ((uint8_t *) NRF_WDT + (uint32_t) task + 0x80uL)) = 0;
}
__STATIC_INLINE void nrf_wdt_publish_set(nrf_wdt_event_t event,
uint8_t channel)
{
*((volatile uint32_t *) ((uint8_t *) NRF_WDT + (uint32_t) event + 0x80uL)) =
((uint32_t)channel | WDT_PUBLISH_TIMEOUT_EN_Msk);
}
__STATIC_INLINE void nrf_wdt_publish_clear(nrf_wdt_event_t event)
{
*((volatile uint32_t *) ((uint8_t *) NRF_WDT + (uint32_t) event + 0x80uL)) = 0;
}
#endif // defined(DPPI_PRESENT)
__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
{
return ((uint32_t)NRF_WDT + (uint32_t)task);
}
__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
{
return ((uint32_t)NRF_WDT + (uint32_t)event);
}
__STATIC_INLINE bool nrf_wdt_started(void)
{
return (bool)(NRF_WDT->RUNSTATUS);
}
__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
{
return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
}
__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
{
NRF_WDT->CRV = reload_value;
}
__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
{
return (uint32_t)NRF_WDT->CRV;
}
__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
{
NRF_WDT->RREN |= 0x1UL << rr_register;
}
__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
{
NRF_WDT->RREN &= ~(0x1UL << rr_register);
}
__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
{
return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
}
__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 // SUPPRESS_INLINE_IMPLEMENTATION
/** @} */
#ifdef __cplusplus
}
#endif
#endif // NRF_WDT_H__