123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- /***************************************************************************//**
- * \file cy_utils.h
- *
- * \brief
- * Basic utility macros and functions.
- *
- ********************************************************************************
- * \copyright
- * Copyright 2018-2020 Cypress Semiconductor Corporation
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *******************************************************************************/
- /**
- * \addtogroup group_utils Utilities
- * \ingroup group_abstraction
- * \{
- * Basic utility macros and functions.
- */
- #if !defined(CY_UTILS_H)
- #define CY_UTILS_H
- #if defined(__cplusplus)
- extern "C" {
- #endif
- /** Simple macro to supress the unused parameter warning by casting to void. */
- #define CY_UNUSED_PARAMETER(x) ( (void)(x) )
- /** Halt the processor in the debug state
- */
- static inline void CY_HALT(void)
- {
- __asm(" bkpt 1");
- }
- #ifdef CY_ASSERT
- #undef CY_ASSERT
- #endif /* ifdef(CY_ASSERT) */
- /** Utility macro when neither NDEBUG or CY_NO_ASSERT is not declared to check a condition and, if false, trigger a breakpoint */
- #if defined(NDEBUG) || defined(CY_NO_ASSERT)
- #define CY_ASSERT(x) do { \
- } while(0)
- #else
- #define CY_ASSERT(x) do { \
- if(!(x)) \
- { \
- CY_HALT(); \
- } \
- } while(0)
- #endif /* defined(NDEBUG) */
- /*******************************************************************************
- * Data manipulation defines
- *******************************************************************************/
- /** Get the lower 8 bits of a 16-bit value. */
- #define CY_LO8(x) ((uint8_t) ((x) & 0xFFU))
- /** Get the upper 8 bits of a 16-bit value. */
- #define CY_HI8(x) ((uint8_t) ((uint16_t)(x) >> 8U))
- /** Get the lower 16 bits of a 32-bit value. */
- #define CY_LO16(x) ((uint16_t) ((x) & 0xFFFFU))
- /** Get the upper 16 bits of a 32-bit value. */
- #define CY_HI16(x) ((uint16_t) ((uint32_t)(x) >> 16U))
- /** Swap the byte ordering of a 16-bit value */
- #define CY_SWAP_ENDIAN16(x) ((uint16_t)(((x) << 8U) | (((x) >> 8U) & 0x00FFU)))
- /** Swap the byte ordering of a 32-bit value */
- #define CY_SWAP_ENDIAN32(x) ((uint32_t)((((x) >> 24U) & 0x000000FFU) | (((x) & 0x00FF0000U) >> 8U) | \
- (((x) & 0x0000FF00U) << 8U) | ((x) << 24U)))
- /** Swap the byte ordering of a 64-bit value */
- #define CY_SWAP_ENDIAN64(x) ((uint64_t) (((uint64_t) CY_SWAP_ENDIAN32((uint32_t)(x)) << 32U) | \
- CY_SWAP_ENDIAN32((uint32_t)((x) >> 32U))))
- /*******************************************************************************
- * Memory model definitions
- *******************************************************************************/
- #if defined(__ARMCC_VERSION)
- /** To create cross compiler compatible code, use the CY_NOINIT, CY_SECTION, CY_UNUSED, CY_ALIGN
- * attributes at the first place of declaration/definition.
- * For example: CY_NOINIT uint32_t noinitVar;
- */
- #if (__ARMCC_VERSION >= 6010050)
- #define CY_NOINIT __attribute__ ((section(".noinit")))
- #else
- #define CY_NOINIT __attribute__ ((section(".noinit"), zero_init))
- #endif /* (__ARMCC_VERSION >= 6010050) */
- #define CY_SECTION(name) __attribute__ ((section(name)))
- #define CY_UNUSED __attribute__ ((unused))
- #define CY_NOINLINE __attribute__ ((noinline))
- /* Specifies the minimum alignment (in bytes) for variables of the specified type. */
- #define CY_ALIGN(align) __ALIGNED(align)
- #define CY_RAMFUNC_BEGIN __attribute__ ((section(".cy_ramfunc")))
- #define CY_RAMFUNC_END
- #elif defined (__GNUC__)
- #if defined (__clang__)
- #define CY_NOINIT __attribute__ ((section("__DATA, __noinit")))
- #define CY_SECTION(name) __attribute__ ((section("__DATA, "name)))
- #define CY_RAMFUNC_BEGIN __attribute__ ((section("__DATA, .cy_ramfunc")))
- #define CY_RAMFUNC_END
- #else
- #define CY_NOINIT __attribute__ ((section(".noinit")))
- #define CY_SECTION(name) __attribute__ ((section(name)))
- #define CY_RAMFUNC_BEGIN __attribute__ ((section(".cy_ramfunc")))
- #define CY_RAMFUNC_END
- #endif
-
- #define CY_UNUSED __attribute__ ((unused))
- #define CY_NOINLINE __attribute__ ((noinline))
- #define CY_ALIGN(align) __ALIGNED(align)
- #elif defined (__ICCARM__)
- #define CY_PRAGMA(x) _Pragma(#x)
- #define CY_NOINIT __no_init
- #define CY_SECTION(name) CY_PRAGMA(location = name)
- #define CY_UNUSED
- #define CY_NOINLINE CY_PRAGMA(optimize = no_inline)
- #define CY_RAMFUNC_BEGIN CY_PRAGMA(diag_suppress = Ta023) __ramfunc
- #define CY_RAMFUNC_END CY_PRAGMA(diag_default = Ta023)
- #if (__VER__ < 8010001)
- #define CY_ALIGN(align) CY_PRAGMA(data_alignment = align)
- #else
- #define CY_ALIGN(align) __ALIGNED(align)
- #endif /* (__VER__ < 8010001) */
- #else
- #error "An unsupported toolchain"
- #endif /* (__ARMCC_VERSION) */
- /*******************************************************************************
- * Macro Name: CY_GET_REG8(addr)
- ****************************************************************************//**
- *
- * Reads the 8-bit value from the specified address. This function can't be
- * used to access the Core register, otherwise a fault occurs.
- *
- * \param addr The register address.
- *
- * \return The read value.
- *
- *******************************************************************************/
- #define CY_GET_REG8(addr) (*((const volatile uint8_t *)(addr)))
- /*******************************************************************************
- * Macro Name: CY_SET_REG8(addr, value)
- ****************************************************************************//**
- *
- * Writes an 8-bit value to the specified address. This function can't be
- * used to access the Core register, otherwise a fault occurs.
- *
- * \param addr The register address.
- *
- * \param value The value to write.
- *
- *******************************************************************************/
- #define CY_SET_REG8(addr, value) (*((volatile uint8_t *)(addr)) = (uint8_t)(value))
- /*******************************************************************************
- * Macro Name: CY_GET_REG16(addr)
- ****************************************************************************//**
- *
- * Reads the 16-bit value from the specified address.
- *
- * \param addr The register address.
- *
- * \return The read value.
- *
- *******************************************************************************/
- #define CY_GET_REG16(addr) (*((const volatile uint16_t *)(addr)))
- /*******************************************************************************
- * Macro Name: CY_SET_REG16(addr, value)
- ****************************************************************************//**
- *
- * Writes the 16-bit value to the specified address.
- *
- * \param addr The register address.
- *
- * \param value The value to write.
- *
- *******************************************************************************/
- #define CY_SET_REG16(addr, value) (*((volatile uint16_t *)(addr)) = (uint16_t)(value))
- /*******************************************************************************
- * Macro Name: CY_GET_REG24(addr)
- ****************************************************************************//**
- *
- * Reads the 24-bit value from the specified address.
- *
- * \param addr The register address.
- *
- * \return The read value.
- *
- *******************************************************************************/
- #define CY_GET_REG24(addr) (((uint32_t) (*((const volatile uint8_t *)(addr)))) | \
- (((uint32_t) (*((const volatile uint8_t *)(addr) + 1))) << 8U) | \
- (((uint32_t) (*((const volatile uint8_t *)(addr) + 2))) << 16U))
- /*******************************************************************************
- * Macro Name: CY_SET_REG24(addr, value)
- ****************************************************************************//**
- *
- * Writes the 24-bit value to the specified address.
- *
- * \param addr The register address.
- *
- * \param value The value to write.
- *
- *******************************************************************************/
- #define CY_SET_REG24(addr, value) do \
- { \
- (*((volatile uint8_t *) (addr))) = (uint8_t)(value); \
- (*((volatile uint8_t *) (addr) + 1)) = (uint8_t)((value) >> 8U); \
- (*((volatile uint8_t *) (addr) + 2)) = (uint8_t)((value) >> 16U); \
- } \
- while(0)
- /*******************************************************************************
- * Macro Name: CY_GET_REG32(addr)
- ****************************************************************************//**
- *
- * Reads the 32-bit value from the specified register. The address is the little
- * endian order (LSB in lowest address).
- *
- * \param addr The register address.
- *
- * \return The read value.
- *
- *******************************************************************************/
- #define CY_GET_REG32(addr) (*((const volatile uint32_t *)(addr)))
- /*******************************************************************************
- * Macro Name: CY_SET_REG32(addr, value)
- ****************************************************************************//**
- *
- * Writes the 32-bit value to the specified register. The address is the little
- * endian order (LSB in lowest address).
- *
- * \param addr The register address.
- *
- * \param value The value to write.
- *
- *******************************************************************************/
- #define CY_SET_REG32(addr, value) (*((volatile uint32_t *)(addr)) = (uint32_t)(value))
- /*******************************************************************************
- * Macro Name: _CLR_SET_FLD32U
- ****************************************************************************//**
- *
- * The macro for setting a register with a name field and value for providing
- * get-clear-modify-write operations.
- * Returns a resulting value to be assigned to the register.
- *
- *******************************************************************************/
- #define _CLR_SET_FLD32U(reg, field, value) (((reg) & ((uint32_t)(~(field ## _Msk)))) | (_VAL2FLD(field, value)))
- /*******************************************************************************
- * Macro Name: CY_REG32_CLR_SET
- ****************************************************************************//**
- *
- * Uses _CLR_SET_FLD32U macro for providing get-clear-modify-write
- * operations with a name field and value and writes a resulting value
- * to the 32-bit register.
- *
- *******************************************************************************/
- #define CY_REG32_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD32U((reg), field, (value)))
- /*******************************************************************************
- * Macro Name: _CLR_SET_FLD16U
- ****************************************************************************//**
- *
- * The macro for setting a 16-bit register with a name field and value for providing
- * get-clear-modify-write operations.
- * Returns a resulting value to be assigned to the 16-bit register.
- *
- *******************************************************************************/
- #define _CLR_SET_FLD16U(reg, field, value) ((uint16_t)(((reg) & ((uint16_t)(~(field ## _Msk)))) | \
- ((uint16_t)_VAL2FLD(field, value))))
-
-
- /*******************************************************************************
- * Macro Name: CY_REG16_CLR_SET
- ****************************************************************************//**
- *
- * Uses _CLR_SET_FLD16U macro for providing get-clear-modify-write
- * operations with a name field and value and writes a resulting value
- * to the 16-bit register.
- *
- *******************************************************************************/
- #define CY_REG16_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD16U((reg), field, (value)))
- /*******************************************************************************
- * Macro Name: _CLR_SET_FLD8U
- ****************************************************************************//**
- *
- * The macro for setting a 8-bit register with a name field and value for providing
- * get-clear-modify-write operations.
- * Returns a resulting value to be assigned to the 8-bit register.
- *
- *******************************************************************************/
- #define _CLR_SET_FLD8U(reg, field, value) ((uint8_t)(((reg) & ((uint8_t)(~(field ## _Msk)))) | \
- ((uint8_t)_VAL2FLD(field, value))))
-
-
- /*******************************************************************************
- * Macro Name: CY_REG8_CLR_SET
- ****************************************************************************//**
- *
- * Uses _CLR_SET_FLD8U macro for providing get-clear-modify-write
- * operations with a name field and value and writes a resulting value
- * to the 8-bit register.
- *
- *******************************************************************************/
- #define CY_REG8_CLR_SET(reg, field, value) ((reg) = _CLR_SET_FLD8U((reg), field, (value)))
- /*******************************************************************************
- * Macro Name: _BOOL2FLD
- ****************************************************************************//**
- *
- * Returns a field mask if the value is not false.
- * Returns 0, if the value is false.
- *
- *******************************************************************************/
- #define _BOOL2FLD(field, value) (((value) != false) ? (field ## _Msk) : 0UL)
- /*******************************************************************************
- * Macro Name: _FLD2BOOL
- ****************************************************************************//**
- *
- * Returns true, if the value includes the field mask.
- * Returns false, if the value doesn't include the field mask.
- *
- *******************************************************************************/
- #define _FLD2BOOL(field, value) (((value) & (field ## _Msk)) != 0UL)
- /*******************************************************************************
- * Macro Name: CY_SYSLIB_DIV_ROUND
- ****************************************************************************//**
- *
- * Calculates a / b with rounding to the nearest integer,
- * a and b must have the same sign.
- *
- *******************************************************************************/
- #define CY_SYSLIB_DIV_ROUND(a, b) (((a) + ((b) / 2U)) / (b))
- /*******************************************************************************
- * Macro Name: CY_SYSLIB_DIV_ROUNDUP
- ****************************************************************************//**
- *
- * Calculates a / b with rounding up if remainder != 0,
- * both a and b must be positive.
- *
- *******************************************************************************/
- #define CY_SYSLIB_DIV_ROUNDUP(a, b) ((((a) - 1U) / (b)) + 1U)
- #ifdef __cplusplus
- }
- #endif
- #endif /* CY_UTILS_H */
- /** \} group_utils */
|