diff --git a/CMSIS/.cproject b/CMSIS/.cproject new file mode 100644 index 0000000..5f16a37 --- /dev/null +++ b/CMSIS/.cproject @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib-c/.project b/CMSIS/.project similarity index 97% rename from lib-c/.project rename to CMSIS/.project index 0a92347..e2e0ca7 100644 --- a/lib-c/.project +++ b/CMSIS/.project @@ -1,6 +1,6 @@ - lib-c + CMSIS diff --git a/lib-network/.settings/language.settings.xml b/CMSIS/.settings/language.settings.xml similarity index 50% rename from lib-network/.settings/language.settings.xml rename to CMSIS/.settings/language.settings.xml index 5b37a73..ed16b20 100644 --- a/lib-network/.settings/language.settings.xml +++ b/CMSIS/.settings/language.settings.xml @@ -1,14 +1,11 @@ - + + - - - - diff --git a/lib-c++/.settings/org.eclipse.core.resources.prefs b/CMSIS/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from lib-c++/.settings/org.eclipse.core.resources.prefs rename to CMSIS/.settings/org.eclipse.core.resources.prefs diff --git a/CMSIS/Core/Include/cachel1_armv7.h b/CMSIS/Core/Include/cachel1_armv7.h new file mode 100644 index 0000000..abebc95 --- /dev/null +++ b/CMSIS/Core/Include/cachel1_armv7.h @@ -0,0 +1,411 @@ +/****************************************************************************** + * @file cachel1_armv7.h + * @brief CMSIS Level 1 Cache API for Armv7-M and later + * @version V1.0.1 + * @date 19. April 2021 + ******************************************************************************/ +/* + * Copyright (c) 2020-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_CACHEL1_ARMV7_H +#define ARM_CACHEL1_ARMV7_H + +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#ifndef __SCB_DCACHE_LINE_SIZE +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +#ifndef __SCB_ICACHE_LINE_SIZE +#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + +#endif /* ARM_CACHEL1_ARMV7_H */ diff --git a/CMSIS/Core/Include/cmsis_armcc.h b/CMSIS/Core/Include/cmsis_armcc.h new file mode 100644 index 0000000..a955d47 --- /dev/null +++ b/CMSIS/Core/Include/cmsis_armcc.h @@ -0,0 +1,888 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.3.2 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; + __ISB(); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/CMSIS/Core/Include/cmsis_armclang.h b/CMSIS/Core/Include/cmsis_armclang.h new file mode 100644 index 0000000..6911417 --- /dev/null +++ b/CMSIS/Core/Include/cmsis_armclang.h @@ -0,0 +1,1503 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.4.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/CMSIS/Core/Include/cmsis_armclang_ltm.h b/CMSIS/Core/Include/cmsis_armclang_ltm.h new file mode 100644 index 0000000..1e255d5 --- /dev/null +++ b/CMSIS/Core/Include/cmsis_armclang_ltm.h @@ -0,0 +1,1928 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.5.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/CMSIS/Core/Include/cmsis_compiler.h b/CMSIS/Core/Include/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/CMSIS/Core/Include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/CMSIS/Core/Include/cmsis_gcc.h b/CMSIS/Core/Include/cmsis_gcc.h new file mode 100644 index 0000000..67bda4e --- /dev/null +++ b/CMSIS/Core/Include/cmsis_gcc.h @@ -0,0 +1,2211 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.1 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/CMSIS/Core/Include/cmsis_iccarm.h b/CMSIS/Core/Include/cmsis_iccarm.h new file mode 100644 index 0000000..65b824b --- /dev/null +++ b/CMSIS/Core/Include/cmsis_iccarm.h @@ -0,0 +1,1002 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.3.0 + * @date 14. April 2021 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2021 IAR Systems +// Copyright (c) 2017-2021 Arm Limited. All rights reserved. +// +// 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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#undef __WEAK /* undo the definition from DLib_Defaults.h */ +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + +#ifndef __PROGRAM_START +#define __PROGRAM_START __iar_program_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP CSTACK$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT CSTACK$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __vector_table +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE @".intvec" +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL STACKSEAL$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __arm_wsr("CONTROL", control); + __iar_builtin_ISB(); +} + + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __arm_wsr("CONTROL_NS", control); + __iar_builtin_ISB(); +} + + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM volatile("RRX %0, %1" : "=r"(result) : "r" (value)); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + __iar_builtin_ISB(); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM volatile ("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM volatile ("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM volatile ("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM volatile ("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM volatile ("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM volatile ("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/CMSIS/Core/Include/cmsis_version.h b/CMSIS/Core/Include/cmsis_version.h new file mode 100644 index 0000000..8b4765f --- /dev/null +++ b/CMSIS/Core/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/CMSIS/Core/Include/core_cm3.h b/CMSIS/Core/Include/core_cm3.h new file mode 100644 index 0000000..74fb87e --- /dev/null +++ b/CMSIS/Core/Include/core_cm3.h @@ -0,0 +1,1943 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ +#endif + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/Core/Include/core_cm4.h b/CMSIS/Core/Include/core_cm4.h new file mode 100644 index 0000000..e21cd14 --- /dev/null +++ b/CMSIS/Core/Include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/Core/Include/core_cm7.h b/CMSIS/Core/Include/core_cm7.h new file mode 100644 index 0000000..010506e --- /dev/null +++ b/CMSIS/Core/Include/core_cm7.h @@ -0,0 +1,2366 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.1.6 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ + uint32_t RESERVED7[5U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< \deprecated SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< \deprecated SCB CACR: ECCEN Mask */ + +#define SCB_CACR_ECCDIS_Pos 1U /*!< SCB CACR: ECCDIS Position */ +#define SCB_CACR_ECCDIS_Msk (1UL << SCB_CACR_ECCDIS_Pos) /*!< SCB CACR: ECCDIS Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBSCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBSCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBSCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/Core/Include/mpu_armv7.h b/CMSIS/Core/Include/mpu_armv7.h new file mode 100644 index 0000000..d9eedf8 --- /dev/null +++ b/CMSIS/Core/Include/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/CMSIS/Core/Include/tz_context.h b/CMSIS/Core/Include/tz_context.h new file mode 100644 index 0000000..0d09749 --- /dev/null +++ b/CMSIS/Core/Include/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/CMSIS/LICENSE.txt b/CMSIS/LICENSE.txt new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/CMSIS/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/README.md b/README.md index a21a8b1..72798d8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![GitHub](https://img.shields.io/github/license/vanvught/GD32F450VI-Bootloader-TFTP) -[![C++ Standard](https://img.shields.io/badge/C%2B%2B-11-blue.svg)](https://img.shields.io/badge/C%2B%2B-11%-blue.svg) +[![C++ Standard](https://img.shields.io/badge/C%2B%2B-20-blue.svg)](https://img.shields.io/badge/C%2B%2B-11%-blue.svg) ![GitHub issues](https://img.shields.io/github/issues-raw/vanvught/GD32F450VI-Bootloader-TFTP) ![GitHub contributors](https://img.shields.io/github/contributors/vanvught/GD32F450VI-Bootloader-TFTP) ![GitHub Sponsors](https://img.shields.io/github/sponsors/vanvught) @@ -9,46 +9,6 @@ # GD32F450VI Bootloader TFTP -This bootloader will install your application by means of the TFTP protocol. There is no need to change your application code. -Per default DHCP is used for obtaining the ip-address. - -The bootloader is active during reset of the board: - -* Or when the `KEY_BOOTLOADER_TFTP_GPIO_PINx` is pressed. Which is defined in file `lib-gd32/include/board/gd32f450vi.h`. -* Or when `bkp_data_read(BKP_DATA_1) == 0xA5A5`. This is set in your application by means of human readable UDP messages. See for more information: [https://www.gd32-dmx.org/bootloader.html](https://www.gd32-dmx.org/bootloader.html). There is also a sample Java UI application available for working with the UDP messages: [https://github.com/vanvught/GD32F-Firmware-Update-UI](https://github.com/vanvught/GD32F-Firmware-Update-UI) - -Otherwise the bootloader will directly jump to your application. With the snippet: - - // 8. Call the reset handler - const uint32_t* reset_p = (uint32_t *)(FLASH_BASE + OFFSET_UIMAGE + 4); - asm volatile ("bx %0;" : : "r"(*reset_p)); - -The bootloader can be installed with the tools supplied by GigaDevice -> [http://www.gd32mcu.com/en/download/7?kw=GD32F4](http://www.gd32mcu.com/en/download/7?kw=GD32F4) - -The limitation for the firmware file to be uploaded is given by the RAM available. With the 256K RAM (RAMADD) we have no firmware file size limit with the 224K avaiavle flashrom. - -See also [https://www.gd32-dmx.org/bootloader.html](https://www.gd32-dmx.org/bootloader.html) - -File: `spiflashinstall.h` - - # elif defined (BOARD_GD32F450VI) - # define OFFSET_UIMAGE 0x008000 // 32K - # define FIRMWARE_MAX_SIZE (224 * 1024) // 224K - # endif - -There is just 224KB flash starting at 0x08008000 - -The change to be made in your build configuration is in the file `gd32f450vi_flash.ld `. - - MEMORY - { - FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 256K - 0x8000 - TCMSRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K - RAMADD (xrw) : ORIGIN = 0x20030000, LENGTH = 256K - BKPSRAM (rw) : ORIGIN = 0x40024000, LENGTH = 4K - } - -The `FLASH ORIGIN` must match the `OFFSET_UIMAGE` from the bootloader file `spiflashinstall.h` +See for more information: [https://www.gd32-dmx.org/bootloader.html](https://www.gd32-dmx.org/bootloader.html). The code for the bootloader is a fork from [https://github.com/vanvught/rpidmx512](https://github.com/vanvught/rpidmx512). In order to reduce the memory footprint, some functions are not available. \ No newline at end of file diff --git a/bootloader-tftp/.cproject b/bootloader-tftp/.cproject index 5d6ed8c..bf73482 100644 --- a/bootloader-tftp/.cproject +++ b/bootloader-tftp/.cproject @@ -23,7 +23,6 @@ diff --git a/bootloader-tftp/.settings/language.settings.xml b/bootloader-tftp/.settings/language.settings.xml index a63a80a..44d1274 100644 --- a/bootloader-tftp/.settings/language.settings.xml +++ b/bootloader-tftp/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + diff --git a/bootloader-tftp/Common.mk b/bootloader-tftp/Common.mk new file mode 100644 index 0000000..54615e4 --- /dev/null +++ b/bootloader-tftp/Common.mk @@ -0,0 +1,15 @@ +DEFINES+=DISABLE_JSON +DEFINES+=DISABLE_RTC +DEFINES+=DISABLE_FS +DEFINES+=DISABLE_PRINTF_FLOAT + +DEFINES+=ENABLE_TFTP_SERVER +DEFINES+=CONFIG_REMOTECONFIG_MINIMUM + +DEFINES+=UDP_MAX_PORTS_ALLOWED=3 + +DEFINES+=RTL8201F_LED1_LINK_ALL + +SRCDIR+=firmware lib + +LIBS+=remoteconfig flashcodeinstall configstore display flashcode flash diff --git a/bootloader-tftp/Makefile-16x4u-i2c.GD32 b/bootloader-tftp/Makefile-16x4u-i2c.GD32 new file mode 100644 index 0000000..64c3a09 --- /dev/null +++ b/bootloader-tftp/Makefile-16x4u-i2c.GD32 @@ -0,0 +1,15 @@ +BOARD=BOARD_GD32F450VI + +DEFINES =CONFIG_STORE_USE_I2C + +DEFINES+=DEBUG_STACK + +DEFINES+=NDEBUG + +SRCDIR= +LIBS= + +include Common.mk +include ../firmware-template-gd32/Rules.mk + +prerequisites: diff --git a/bootloader-tftp/Makefile-16x4u.GD32 b/bootloader-tftp/Makefile-16x4u.GD32 index 0635151..513ed04 100644 --- a/bootloader-tftp/Makefile-16x4u.GD32 +++ b/bootloader-tftp/Makefile-16x4u.GD32 @@ -1,27 +1,16 @@ BOARD=BOARD_16X4U_PIXEL -DEFINES =DISABLE_JSON -DEFINES+=DISABLE_RTC -DEFINES+=DISABLE_FS -DEFINES+=DISABLE_PRINTF_FLOAT - -DEFINES+=ENABLE_TFTP_SERVER -DEFINES+=CONFIG_REMOTECONFIG_MINIMUM - -DEFINES+=UDP_MAX_PORTS_ALLOWED=2 - -DEFINES+=ENET_LINK_CHECK_REG_POLL - -DEFINES+=CONFIG_STORE_USE_SPI +DEFINES =CONFIG_STORE_USE_SPI +DEFINES+=CONFIG_USE_SOFTUART0 DEFINES+=DEBUG_STACK DEFINES+=NDEBUG -SRCDIR=firmware lib - -LIBS=remoteconfig flashcodeinstall configstore display flashcode flash +SRCDIR= +LIBS= +include Common.mk include ../firmware-template-gd32/Rules.mk prerequisites: diff --git a/bootloader-tftp/Makefile-i2c.GD32 b/bootloader-tftp/Makefile-i2c.GD32 new file mode 100644 index 0000000..64c3a09 --- /dev/null +++ b/bootloader-tftp/Makefile-i2c.GD32 @@ -0,0 +1,15 @@ +BOARD=BOARD_GD32F450VI + +DEFINES =CONFIG_STORE_USE_I2C + +DEFINES+=DEBUG_STACK + +DEFINES+=NDEBUG + +SRCDIR= +LIBS= + +include Common.mk +include ../firmware-template-gd32/Rules.mk + +prerequisites: diff --git a/bootloader-tftp/Makefile.GD32 b/bootloader-tftp/Makefile.GD32 index bf64d0b..6211396 100644 --- a/bootloader-tftp/Makefile.GD32 +++ b/bootloader-tftp/Makefile.GD32 @@ -1,27 +1,16 @@ BOARD=BOARD_GD32F450VI -DEFINES =DISABLE_JSON -DEFINES+=DISABLE_RTC -DEFINES+=DISABLE_FS -DEFINES+=DISABLE_PRINTF_FLOAT - -DEFINES+=ENABLE_TFTP_SERVER -DEFINES+=CONFIG_REMOTECONFIG_MINIMUM - -DEFINES+=UDP_MAX_PORTS_ALLOWED=2 - -DEFINES+=ENET_LINK_CHECK_REG_POLL - -DEFINES+=CONFIG_STORE_USE_I2C +DEFINES =CONFIG_STORE_USE_SPI +DEFINES+=CONFIG_USE_SOFTUART0 DEFINES+=DEBUG_STACK DEFINES+=NDEBUG -SRCDIR=firmware lib - -LIBS=remoteconfig flashcodeinstall configstore display flashcode flash +SRCDIR= +LIBS= +include Common.mk include ../firmware-template-gd32/Rules.mk prerequisites: diff --git a/bootloader-tftp/firmware/main.cpp b/bootloader-tftp/firmware/main.cpp index f8a55fa..ae03bd7 100644 --- a/bootloader-tftp/firmware/main.cpp +++ b/bootloader-tftp/firmware/main.cpp @@ -2,7 +2,7 @@ * @file main.cpp * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.nl +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,12 +29,10 @@ #include "hardware.h" #include "network.h" #include "networkconst.h" -#include "storenetwork.h" #include "display.h" #include "remoteconfig.h" #include "remoteconfigparams.h" -#include "storeremoteconfig.h" #include "firmwareversion.h" #include "software_version.h" @@ -50,24 +48,29 @@ void Hardware::RebootHandler() { int main(void) { rcu_periph_clock_enable(KEY_BOOTLOADER_TFTP_RCU_GPIOx); -#if !defined (GD32F4XX) - rcu_periph_clock_enable(RCU_AF); - rcu_periph_clock_enable(KEY_BOOTLOADER_TFTP_RCU_GPIOx); - gpio_init(KEY_BOOTLOADER_TFTP_GPIOx, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY_BOOTLOADER_TFTP_GPIO_PINx); -#else +#if defined (GD32F4XX) || defined (GD32H7XX) rcu_periph_clock_enable(RCU_PMU); +# if defined (GD32F4XX) pmu_backup_ldo_config(PMU_BLDOON_ON); +# endif rcu_periph_clock_enable(RCU_BKPSRAM); pmu_backup_write_enable(); - gpio_af_set(KEY_BOOTLOADER_TFTP_GPIOx, GPIO_AF_0, KEY_BOOTLOADER_TFTP_GPIO_PINx); gpio_mode_set(KEY_BOOTLOADER_TFTP_GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, KEY_BOOTLOADER_TFTP_GPIO_PINx); +#else + rcu_periph_clock_enable(RCU_AF); + rcu_periph_clock_enable(KEY_BOOTLOADER_TFTP_RCU_GPIOx); + if constexpr (KEY_BOOTLOADER_TFTP_GPIOx == GPIOA) { + if constexpr ((KEY_BOOTLOADER_TFTP_GPIO_PINx == GPIO_PIN_13) || (KEY_BOOTLOADER_TFTP_GPIO_PINx == GPIO_PIN_14)) { + gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); + } + } + gpio_init(KEY_BOOTLOADER_TFTP_GPIOx, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY_BOOTLOADER_TFTP_GPIO_PINx); #endif const auto isNotRemote = (bkp_data_read(BKP_DATA_1) != 0xA5A5); - const auto isNotKey = (gpio_input_bit_get(KEY_BOOTLOADER_TFTP_GPIOx, KEY_BOOTLOADER_TFTP_GPIO_PINx)); + const auto isNotKey = (gpio_input_bit_get(KEY_BOOTLOADER_TFTP_GPIOx, KEY_BOOTLOADER_TFTP_GPIO_PINx)); if (isNotRemote && isNotKey) { - // https://developer.arm.com/documentation/ka001423/1-0 // https://developer.arm.com/documentation/ka001423/1-0 //1. Disable interrupt response. __disable_irq(); @@ -100,29 +103,23 @@ int main(void) { Hardware hw; Display display(4); ConfigStore configStore; - StoreNetwork storeNetwork; - Network nw(&storeNetwork); + Network nw; FirmwareVersion fw(SOFTWARE_VERSION, __DATE__, __TIME__); FlashCodeInstall flashCodeInstall; printf("Remote=%c, Key=%c\n", isNotRemote ? 'N' : 'Y', isNotKey ? 'N' : 'Y'); fw.Print("Bootloader TFTP Server"); - nw.Print(); hw.SetMode(hardware::ledblink::Mode::OFF_ON); RemoteConfig remoteConfig(remoteconfig::Node::BOOTLOADER_TFTP, remoteconfig::Output::CONFIG); - StoreRemoteConfig storeRemoteConfig; - RemoteConfigParams remoteConfigParams(&storeRemoteConfig); - - if (remoteConfigParams.Load()) { - remoteConfigParams.Set(&remoteConfig); - } + RemoteConfigParams remoteConfigParams; + remoteConfigParams.Load(); + remoteConfigParams.Set(&remoteConfig); remoteConfig.SetEnableReboot(true); - network::display_ip(); display.Printf(3, "Bootloader TFTP Srvr"); hw.SetMode(hardware::ledblink::Mode::FAST); diff --git a/bootloader-tftp/gd32f4xx.size b/bootloader-tftp/gd32f4xx.size deleted file mode 100644 index 93c7fb3..0000000 --- a/bootloader-tftp/gd32f4xx.size +++ /dev/null @@ -1,15 +0,0 @@ -build_gd32/main.elf : -section size addr -.vectors 0x1ac 0x8000000 -.text 0x629c 0x80001ac -.rodata 0xc18 0x8006448 -.data 0x70 0x20000000 -.stack 0x800 0x10000000 -.tcmsram 0x2690 0x10000800 -.heap 0x400 0x10002e90 -.bss 0x3a6bc 0x20030000 -.ramadd 0x0 0x2006a6bc -.bkpsram 0x0 0x40024000 -Total 0x44a1c - - diff --git a/bootloader-tftp/include/software_version.h b/bootloader-tftp/include/software_version.h index 46a34e9..58b5682 100644 --- a/bootloader-tftp/include/software_version.h +++ b/bootloader-tftp/include/software_version.h @@ -2,7 +2,7 @@ * @file software_version.h * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,6 @@ #ifndef SOFTWARE_VERSION_H_ #define SOFTWARE_VERSION_H_ -constexpr char SOFTWARE_VERSION[] = "2.0"; +constexpr char SOFTWARE_VERSION[] = "2.1"; #endif /* SOFTWARE_VERSION_H_ */ diff --git a/bootloader-tftp/lib/networkdisplay.cpp b/bootloader-tftp/lib/networkdisplay.cpp index 4c78934..c5021de 100644 --- a/bootloader-tftp/lib/networkdisplay.cpp +++ b/bootloader-tftp/lib/networkdisplay.cpp @@ -2,7 +2,7 @@ * @file networkdisplay.cpp * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,31 +25,36 @@ #include -#include "network.h" - #include "display.h" -#include "display7segment.h" -namespace network { +#include "network.h" +#include "net/protocol/dhcp.h" + +namespace net { static constexpr auto LINE_IP = 2U; void display_emac_config() { - Display::Get()->ClearEndOfLine(); - Display::Get()->Printf(LINE_IP, "Ethernet config"); + Display::Get()->ClearLine(LINE_IP); + Display::Get()->PutString("Ethernet config"); } void display_emac_start() { - Display::Get()->ClearEndOfLine(); - Display::Get()->Printf(LINE_IP, "Ethernet start"); + Display::Get()->ClearLine(LINE_IP); + Display::Get()->PutString("Ethernet start"); } void display_emac_status(const bool isLinkUp) { - Display::Get()->ClearEndOfLine(); - Display::Get()->Printf(LINE_IP, "Ethernet Link %s", isLinkUp ? "UP" : "DOWN"); + Display::Get()->ClearLine(LINE_IP); + Display::Get()->PutString("Ethernet Link "); + if (isLinkUp) { + Display::Get()->PutString("UP"); + } else { + Display::Get()->PutString("DOWN"); + } } void display_ip() { - Display::Get()->ClearEndOfLine(); + Display::Get()->ClearLine(LINE_IP); Display::Get()->Printf(LINE_IP, "" IPSTR "/%d %c", IP2STR(Network::Get()->GetIp()), Network::Get()->GetNetmaskCIDR(), Network::Get()->GetAddressingMode()); } @@ -64,31 +69,27 @@ void display_hostname() { } void display_emac_shutdown() { - Display::Get()->ClearEndOfLine(); + Display::Get()->ClearLine(LINE_IP); Display::Get()->PutString("Ethernet shutdown"); } -void display_dhcp_status(network::dhcp::ClientStatus nStatus) { +void display_dhcp_status(net::dhcp::State state) { Display::Get()->ClearLine(LINE_IP); - switch (nStatus) { - case network::dhcp::ClientStatus::IDLE: + switch (state) { + case net::dhcp::State::STATE_OFF: break; - case network::dhcp::ClientStatus::RENEW: + case net::dhcp::State::STATE_RENEWING: Display::Get()->PutString("DHCP renewing"); - Display::Get()->Status(Display7SegmentMessage::INFO_DHCP); break; - case network::dhcp::ClientStatus::GOT_IP: + case net::dhcp::State::STATE_BOUND: Display::Get()->PutString("Got IP"); - Display::Get()->Status(Display7SegmentMessage::INFO_NONE); break; - case network::dhcp::ClientStatus::RETRYING: - Display::Get()->PutString("DHCP retrying"); - Display::Get()->Status(Display7SegmentMessage::INFO_DHCP); + case net::dhcp::State::STATE_REQUESTING: + Display::Get()->PutString("DHCP requesting"); break; - case network::dhcp::ClientStatus::FAILED: + case net::dhcp::State::STATE_BACKING_OFF: Display::Get()->PutString("DHCP Error"); - Display::Get()->Status(Display7SegmentMessage::ERROR_DHCP); break; default: break; diff --git a/firmware-template-gd32/Board.mk b/firmware-template-gd32/Board.mk new file mode 100644 index 0000000..bc44a93 --- /dev/null +++ b/firmware-template-gd32/Board.mk @@ -0,0 +1,108 @@ +$(info "Board.mk") + +ifndef BOARD + $(error BOARD is not set) +endif + +ifndef DEFINES + DEFINES= +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F103RC) + MCU=GD32F103RC + DEFINES+=-DCONFIG_STORE_USE_ROM + DEFINES+=-DNO_EMAC +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F107RC) + MCU=GD32F107RC + DEFINES+=-DCONFIG_STORE_USE_ROM +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F207RG) + MCU=GD32F207RG + DEFINES+=-DCONFIG_STORE_USE_SPI +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F207VC_2) + MCU=GD32F207VC + DEFINES+=-DCONFIG_STORE_USE_ROM + BITBANGING595=1 +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F207VC_4) + MCU=GD32F207VC + DEFINES+=-DCONFIG_STORE_USE_ROM + BITBANGING595=1 +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F303RC) + MCU=GD32F303RC + DEFINES+=-DCONFIG_STORE_USE_ROM + DEFINES+=-DNO_EMAC +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F407RE) + MCU=GD32F407RE + DEFINES+=-DCONFIG_STORE_USE_SPI +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F450VE) + MCU=GD32F450VE + DEFINES+=-DCONFIG_STORE_USE_RAM + BITBANGING595=1 +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F450VI) + MCU=GD32F450VI +endif + +ifeq ($(strip $(BOARD)),BOARD_16X4U_PIXEL) + MCU=GD32F450VI +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F470VG) + MCU=GD32F470VG +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F207C_EVAL) + MCU=GD32F207VC + DEFINES+=-DCONFIG_STORE_USE_ROM +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32F470Z_EVAL) + MCU=GD32F470ZK + DEFINES+=-DCONFIG_STORE_USE_RAM +endif + +ifeq ($(strip $(BOARD)),BOARD_GD32H759I_EVAL) + MCU=GD32H759IM + DEFINES+=-DCONFIG_STORE_USE_ROM +endif + +ifeq ($(strip $(BOARD)),BOARD_BW_OPIDMX4) + BOARD_DMX=4 + DEFINES+=-DCONFIG_STORE_USE_SPI +endif + +ifeq ($(strip $(BOARD)),BOARD_DMX3) + BOARD_DMX=3 + DEFINES+=-DCONFIG_STORE_USE_SPI +endif + +ifeq ($(strip $(BOARD)),BOARD_DMX4) + DEFINES+=-DCONFIG_STORE_USE_SPI + BOARD_DMX=4 +endif + +ifdef BOARD_DMX + ifeq ($(MCU),GD32F207RG) + else ifeq ($(MCU),GD32F407RE) + else + $(error MCU is not support for BOARD_DMX) + endif +endif + +ifndef MCU + $(error BOARD is not configured) +endif \ No newline at end of file diff --git a/firmware-template-gd32/Includes.mk b/firmware-template-gd32/Includes.mk index d13b7f0..71aadc0 100644 --- a/firmware-template-gd32/Includes.mk +++ b/firmware-template-gd32/Includes.mk @@ -1,8 +1,69 @@ -INCLUDES:= -I./include -I../include -I../lib-hal/include -I../lib-debug/include -INCLUDES+=$(addprefix -I,$(EXTRA_INCLUDES)) +$(info "Includes.mk") + +INCLUDES:=-I./include -I../include INCLUDES+=-I../firmware-template-gd32/include INCLUDES+=-I../firmware-template-gd32/template +INCLUDES+=-I../CMSIS/Core/Include INCLUDES+=-I../lib-gd32/${FAMILY}/${FAMILY_UC}_standard_peripheral/Include -INCLUDES+=-I../lib-gd32/${FAMILY}/CMSIS INCLUDES+=-I../lib-gd32/${FAMILY}/CMSIS/GD/${FAMILY_UC}/Include -INCLUDES+=-I../lib-gd32/include \ No newline at end of file +INCLUDES+=-I../lib-gd32/include +INCLUDES+=$(addprefix -I,$(EXTRA_INCLUDES)) + +ifeq ($(findstring ENABLE_USB_HOST,$(DEFINES)), ENABLE_USB_HOST) + USB_HOST=1 +endif +ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) + USB_HOST=1 +endif + +ifeq ($(findstring ENABLE_USB_HOST,$(DEFINES)), ENABLE_USB_HOST) + USB_HOST_MSC=1 +endif +ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) + USB_HOST_MSC=1 +endif + +ifdef USB_HOST + INCLUDES+=-I../lib-gd32/device/usb + INCLUDES+=-I../lib-hal/device/usb/host/gd32 +endif + +ifeq ($(findstring gd32f20x,$(FAMILY)), gd32f20x) + ifdef USB_HOST + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F20x_usbfs_library/driver/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F20x_usbfs_library/host/core/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F20x_usbfs_library/ustd/common + ifdef USB_HOST_MSC + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F20x_usbfs_library/host/class/msc/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F20x_usbfs_library/ustd/class/msc + endif + endif +endif + +ifeq ($(findstring gd32f4xx,$(FAMILY)), gd32f4xx) + ifdef USB_HOST + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F4xx_usb_library/driver/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F4xx_usb_library/host/core/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F4xx_usb_library/ustd/common + ifdef USB_HOST_MSC + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F4xx_usb_library/host/class/msc/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32F4xx_usb_library/ustd/class/msc + endif + endif +endif + +ifeq ($(findstring gd32h7xx,$(FAMILY)), gd32h7xx) + ifdef USB_HOST + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32H7xx_usbhs_library/driver/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32H7xx_usbhs_library/host/core/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32H7xx_usbhs_library/ustd/common + ifdef USB_HOST_MSC + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32H7xx_usbhs_library/host/class/msc/Include + INCLUDES+=-I../lib-gd32/${FAMILY}/GD32H7xx_usbhs_library/ustd/class/msc + endif + endif +endif + +ifdef USB_HOST_MSC + INCLUDES+=-I../lib-hal/ff14b/source +endif \ No newline at end of file diff --git a/firmware-template-gd32/Mcu.mk b/firmware-template-gd32/Mcu.mk new file mode 100644 index 0000000..46058e8 --- /dev/null +++ b/firmware-template-gd32/Mcu.mk @@ -0,0 +1,139 @@ +$(info "Mcu.mk") + +ifndef MCU + $(error MCU is not set) +endif + +$(info $$MCU [${MCU}]) + +# Extract upper and lower case versions of MCU name +MCU_UC=$(shell echo $(MCU) | rev | cut -c3- | rev ) +MCU_LC=$(shell echo $(MCU_UC) | tr A-Z a-z ) + +$(info $$MCU [${MCU}]) +$(info $$MCU_LC [${MCU_LC}]) +$(info $$MCU_UC [${MCU_UC}]) + +# Set LINKER, FAMILY, and LINE based on MCU + +ifeq ($(strip $(MCU)),GD32F103RC) + LINKER=$(FIRMWARE_DIR)gd32f103rc_flash.ld + FAMILY=gd32f10x + LINE=gd32f10x_hd +endif + +ifeq ($(strip $(MCU)),GD32F107RC) + LINKER=$(FIRMWARE_DIR)gd32f107rc_flash.ld + FAMILY=gd32f10x + LINE=gd32f10x_cl +endif + +ifeq ($(strip $(MCU)),GD32F207VC) + LINKER=$(FIRMWARE_DIR)gd32f207vc_flash.ld + FAMILY=gd32f20x + LINE=gd32f20x_cl +endif + +ifeq ($(strip $(MCU)),GD32F207RG) + LINKER=$(FIRMWARE_DIR)gd32f207rg_flash.ld + FAMILY=gd32f20x + LINE=gd32f20x_cl +endif + +ifeq ($(strip $(MCU)),GD32F303RC) + LINKER=$(FIRMWARE_DIR)gd32f303rc_flash.ld + FAMILY=gd32f30x + LINE=gd32f30x_hd +endif + +ifeq ($(strip $(MCU)),GD32F407RE) + LINKER=$(FIRMWARE_DIR)gd32f407re_flash.ld + FAMILY=gd32f4xx + LINE=gd32f407 +endif + +ifeq ($(strip $(MCU)),GD32F450VE) + LINKER=$(FIRMWARE_DIR)gd32f450ve_flash.ld + FAMILY=gd32f4xx + LINE=gd32f450 +endif + +ifeq ($(strip $(MCU)),GD32F450VI) + LINKER=$(FIRMWARE_DIR)gd32f450vi_flash.ld + FAMILY=gd32f4xx + LINE=gd32f450 +endif + +ifeq ($(strip $(MCU)),GD32F470VG) + LINKER=$(FIRMWARE_DIR)gd32f470vg_flash.ld + FAMILY=gd32f4xx + LINE=gd32f470 +endif + +ifeq ($(strip $(MCU)),GD32F470ZK) + LINKER=$(FIRMWARE_DIR)gd32f470zk_flash.ld + FAMILY=gd32f4xx + LINE=gd32f470 +endif + +ifeq ($(strip $(MCU)),GD32H759IM) + LINKER=$(FIRMWARE_DIR)gd32h7xx_xM_flash.ld + FAMILY=gd32h7xx + LINE=gd32h759 +endif + +ifndef LINKER + $(error MCU is not configured) +endif + +# Common ARM options for Cortex-M3 +ARMOPS_CM3=-mcpu=cortex-m3 -mthumb -mfloat-abi=soft + +# Common ARM options for Cortex-M4 +ARMOPS_CM4=-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant + +# Common ARM options for Cortex-M7 +ARMOPS_CM7=-mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 -fsingle-precision-constant + +# CMSIS options for FPU present +CMSISOPS_FPU_PRESENT = -D__FPU_PRESENT=1 -DARM_MATH_CM4 + +# Common CMSIS options +CMSISOPS=-D__Vendor_SysTickConfig=0 + +# Set ARM options and CMSIS options based on FAMILY + +ifeq ($(FAMILY),gd32f10x) + ARMOPS=$(ARMOPS_CM3) +endif + +ifeq ($(FAMILY),gd32f20x) + ARMOPS=$(ARMOPS_CM3) +endif + +ifeq ($(FAMILY),gd32f30x) + ARMOPS=$(ARMOPS_CM4) + CMSISOPS+=$(CMSISOPS_FPU_PRESENT) +endif + +ifeq ($(FAMILY),gd32f4xx) + ARMOPS=$(ARMOPS_CM4) + CMSISOPS+=$(CMSISOPS_FPU_PRESENT) +endif + +ifeq ($(FAMILY),gd32h7xx) + ARMOPS=$(ARMOPS_CM7) + CMSISOPS+=-D__FPU_PRESENT=1 -DARM_MATH_CM7 +endif + +FAMILY_UC=$(shell echo $(FAMILY) | tr a-w A-W) +FAMILY_UCA=$(shell echo $(FAMILY) | tr a-z A-Z) +LINE_UC=$(shell echo $(LINE) | tr a-z A-Z) + + +$(info $$FAMILY [${FAMILY}]) +$(info $$FAMILY_UC [${FAMILY_UC}]) +$(info $$FAMILY_UCA [${FAMILY_UCA}]) + +$(info $$LINE [${LINE}]) +$(info $$LINE_UC [${LINE_UC}]) \ No newline at end of file diff --git a/firmware-template-gd32/Rules.mk b/firmware-template-gd32/Rules.mk index 66a03ad..dfc885f 100644 --- a/firmware-template-gd32/Rules.mk +++ b/firmware-template-gd32/Rules.mk @@ -1,3 +1,5 @@ +$(info "Rules.mk") + PREFIX ?= arm-none-eabi- CC = $(PREFIX)gcc @@ -7,36 +9,25 @@ LD = $(PREFIX)ld AR = $(PREFIX)ar BOARD?=BOARD_GD32F450VI -ENET_PHY?=DP83848 -FAMILY?=gd32f4xx -MCU?=gd32f450 - -FAMILY:=$(shell echo $(FAMILY) | tr A-Z a-z) -FAMILY_UC=$(shell echo $(FAMILY) | tr a-w A-W) +ENET_PHY?=RTL8201F -$(info $$FAMILY [${FAMILY}]) -$(info $$FAMILY_UC [${FAMILY_UC}]) - -# Output -TARGET=$(MCU).bin +TARGET=gd32f450.bin LIST=$(FAMILY).list MAP=$(FAMILY).map +SIZE=$(FAMILY).size BUILD=build_gd32/ -# Input -SOURCE = ./ -FIRMWARE_DIR = ./../firmware-template-gd32/ -LINKER = $(FIRMWARE_DIR)/gd32f450vi_flash.ld - -include ../firmware-template/libs.mk - -LIBS+=c++ c gd32 +FIRMWARE_DIR=./../firmware-template-gd32/ -$(info [${LIBS}]) - DEFINES:=$(addprefix -D,$(DEFINES)) +include ../firmware-template-gd32/Board.mk +include ../firmware-template-gd32/Mcu.mk +include ../firmware-template/libs.mk include ../firmware-template-gd32/Includes.mk +include ../firmware-template-gd32/Validate.mk + +LIBS+=gd32 clib # The variable for the libraries include directory LIBINCDIRS:=$(addprefix -I../lib-,$(LIBS)) @@ -46,32 +37,32 @@ LIBINCDIRS+=$(addsuffix /include, $(LIBINCDIRS)) LIBGD32=$(addprefix -L../lib-,$(LIBS)) LIBGD32:=$(addsuffix /lib_gd32, $(LIBGD32)) -# The variable for the ld -l flag +# The variable for the ld -l flag LDLIBS:=$(addprefix -l,$(LIBS)) -# The variables for the dependency check +# The variables for the dependency check LIBDEP=$(addprefix ../lib-,$(LIBS)) -$(info $$LIBDEP [${LIBDEP}]) - -COPS=-DBARE_METAL -DGD32 -DGD32F450 -D$(BOARD) -DPHY_TYPE=$(ENET_PHY) -COPS+=$(DEFINES) $(MAKE_FLAGS) $(INCLUDES) $(LIBINCDIRS) -COPS+=-Os -mcpu=cortex-m4 -mthumb -g -mfloat-abi=hard -fsingle-precision-constant -mfpu=fpv4-sp-d16 -COPS+=-DARM_MATH_CM4 -D__FPU_PRESENT=1 -COPS+=-nostartfiles -ffreestanding -nostdlib -COPS+=-fstack-usage -Wstack-usage=16384 +COPS=-DGD32 -D$(FAMILY_UCA) -D$(LINE_UC) -D$(MCU) -D$(BOARD) -DPHY_TYPE=$(ENET_PHY) +COPS+=$(strip $(DEFINES) $(MAKE_FLAGS) $(INCLUDES) $(LIBINCDIRS)) +COPS+=$(strip $(ARMOPS) $(CMSISOPS)) +COPS+=-Os -nostartfiles -ffreestanding -nostdlib +COPS+=-fstack-usage COPS+=-ffunction-sections -fdata-sections +COPS+=-Wall -Werror -Wpedantic -Wextra -Wunused -Wsign-conversion -Wconversion -Wduplicated-cond -Wlogical-op -CPPOPS=-std=c++11 +CPPOPS=-std=c++20 CPPOPS+=-Wnon-virtual-dtor -Woverloaded-virtual -Wnull-dereference -fno-rtti -fno-exceptions -fno-unwind-tables -#CPPOPS+=-Wuseless-cast -Wold-style-cast +CPPOPS+=-Wuseless-cast -Wold-style-cast CPPOPS+=-fno-threadsafe-statics -LDOPS=--gc-sections --print-gc-sections +LDOPS=--gc-sections --print-gc-sections --print-memory-usage PLATFORM_LIBGCC+= -L $(shell dirname `$(CC) $(COPS) -print-libgcc-file-name`) +PLATFORM_LIBC+= -L $(shell dirname `$(CC) $(COPS) --print-file-name=libc.a`) $(info $$PLATFORM_LIBGCC [${PLATFORM_LIBGCC}]) +$(info $$PLATFORM_LIBC [${PLATFORM_LIBC}]) C_OBJECTS=$(foreach sdir,$(SRCDIR),$(patsubst $(sdir)/%.c,$(BUILD)$(sdir)/%.o,$(wildcard $(sdir)/*.c))) C_OBJECTS+=$(foreach sdir,$(SRCDIR),$(patsubst $(sdir)/%.cpp,$(BUILD)$(sdir)/%.o,$(wildcard $(sdir)/*.cpp))) @@ -82,19 +73,18 @@ BUILD_DIRS:=$(addprefix $(BUILD),$(SRCDIR)) OBJECTS:=$(ASM_OBJECTS) $(C_OBJECTS) define compile-objects -$(BUILD)$1/%.o: $(SOURCE)$1/%.cpp - $(CPP) $(COPS) $(CPPOPS) -c $$< -o $$@ +$(BUILD)$1/%.o: $1/%.cpp + $(CPP) $(COPS) $(CPPOPS) -c $$< -o $$@ -$(BUILD)$1/%.o: $(SOURCE)$1/%.c +$(BUILD)$1/%.o: $1/%.c $(CC) $(COPS) -c $$< -o $$@ - -$(BUILD)$1/%.o: $(SOURCE)$1/%.S + +$(BUILD)$1/%.o: $1/%.S $(CC) $(COPS) -D__ASSEMBLY__ -c $$< -o $$@ endef - all : builddirs prerequisites $(TARGET) - + .PHONY: clean builddirs builddirs: @@ -117,7 +107,7 @@ clean: $(LIBDEP) lisdep: $(LIBDEP) $(LIBDEP): - $(MAKE) -f Makefile.GD32 $(MAKECMDGOALS) 'FAMILY=${FAMILY}' 'BOARD=${BOARD}' 'PHY_TYPE=${ENET_PHY}' 'MAKE_FLAGS=$(DEFINES)' -C $@ + $(MAKE) -f Makefile.GD32 $(MAKECMDGOALS) 'FAMILY=${FAMILY}' 'BOARD=${BOARD}' 'ENET_PHY=${ENET_PHY}' 'MAKE_FLAGS=$(DEFINES)' -C $@ # # Build bin @@ -126,20 +116,18 @@ $(LIBDEP): $(BUILD_DIRS) : mkdir -p $(BUILD_DIRS) -$(BUILD)startup_$(MCU).o : $(FIRMWARE_DIR)/startup_$(MCU).S - $(AS) $(COPS) -D__ASSEMBLY__ -c $(FIRMWARE_DIR)/startup_$(MCU).S -o $(BUILD)startup_$(MCU).o - -$(BUILD)main.elf: Makefile.GD32 $(LINKER) $(BUILD)startup_$(MCU).o $(OBJECTS) $(LIBDEP) - $(LD) $(BUILD)startup_$(MCU).o $(OBJECTS) -Map $(MAP) -T $(LINKER) $(LDOPS) -o $(BUILD)main.elf $(LIBGD32) $(LDLIBS) $(PLATFORM_LIBGCC) -lgcc +$(BUILD)startup_$(LINE).o : $(FIRMWARE_DIR)/startup_$(LINE).S + $(AS) $(COPS) -D__ASSEMBLY__ -c $(FIRMWARE_DIR)/startup_$(LINE).S -o $(BUILD)startup_$(LINE).o + +$(BUILD)hardfault_handler.o : $(FIRMWARE_DIR)/hardfault_handler.c + $(CC) $(COPS) -c $(FIRMWARE_DIR)/hardfault_handler.c -o $(BUILD)hardfault_handler.o + +$(BUILD)main.elf: Makefile.GD32 $(LINKER) $(BUILD)startup_$(LINE).o $(BUILD)hardfault_handler.o $(OBJECTS) $(LIBDEP) + $(LD) $(BUILD)startup_$(LINE).o $(BUILD)hardfault_handler.o $(OBJECTS) -Map $(MAP) -T $(LINKER) $(LDOPS) -o $(BUILD)main.elf $(LIBGD32) $(LDLIBS) $(PLATFORM_LIBGCC) -lgcc $(PREFIX)objdump -D $(BUILD)main.elf | $(PREFIX)c++filt > $(LIST) - $(PREFIX)size -A -x $(BUILD)main.elf > $(FAMILY).size - $(MAKE) -f Makefile.GD32 calculate_unused_ram SIZE_FILE=$(FAMILY).size LINKER_SCRIPT=$(LINKER) + $(PREFIX)size -A -x $(BUILD)main.elf -$(TARGET) : $(BUILD)main.elf - $(PREFIX)objcopy $(BUILD)main.elf --remove-section=.tcmsram* --remove-section=.ramadd* --remove-section=.bkpsram* -O binary $(TARGET) - -$(foreach bdir,$(SRCDIR),$(eval $(call compile-objects,$(bdir)))) +$(TARGET) : $(BUILD)main.elf + $(PREFIX)objcopy $(BUILD)main.elf -O binary $(TARGET) --remove-section=.tcmsram* --remove-section=.sram1* --remove-section=.sram2* --remove-section=.ramadd* --remove-section=.bkpsram* -.PHONY: calculate_unused_ram -calculate_unused_ram: $(FAMILY).size $(LINKER) - @$(FIRMWARE_DIR)/calculate_unused_ram.sh $(FAMILY).size $(LINKER) +$(foreach bdir,$(SRCDIR),$(eval $(call compile-objects,$(bdir)))) diff --git a/firmware-template-gd32/Validate.mk b/firmware-template-gd32/Validate.mk new file mode 100644 index 0000000..9531da3 --- /dev/null +++ b/firmware-template-gd32/Validate.mk @@ -0,0 +1,33 @@ +$(info "Validate.mk") +$(info $$MAKE_FLAGS [${MAKE_FLAGS}]) +$(info $$DEFINES [${DEFINES}]) + +FLAGS:=$(MAKE_FLAGS) +ifeq ($(FLAGS),) + FLAGS:=$(DEFINES) +endif + +ifneq (,$(findstring OUTPUT_DMX_SEND,$(FLAGS))$(findstring CONFIG_RDM,$(FLAGS))$(findstring RDM_CONTROLLER,$(FLAGS))$(findstring LTC,$(FLAGS))) + TIMER6_HAVE_IRQ_HANDLER=1 + ifneq (,$(findstring CONFIG_TIMER6_HAVE_NO_IRQ_HANDLER,$(MAKE_FLAGS))) + $(error CONFIG_TIMER6_HAVE_NO_IRQ_HANDLER is set) + endif +endif + +ifndef TIMER6_HAVE_IRQ_HANDLER + DEFINES+=-DCONFIG_TIMER6_HAVE_NO_IRQ_HANDLER +endif + +ifneq ($(findstring USE_FREE_RTOS,$(FLAGS)),USE_FREE_RTOS) + DEFINES+=-DCONFIG_HAL_USE_SYSTICK +else + DEFINES+=-DCONFIG_HAL_USE_SYSTICK # Temporarily need to fix TIMER10 +endif + +ifeq ($(findstring ENABLE_TFTP_SERVER,$(FLAGS)),ENABLE_TFTP_SERVER) + ifneq ($(findstring CONFIG_HAL_USE_SYSTICK,$(FLAGS)),CONFIG_HAL_USE_SYSTICK) + DEFINES+=-DCONFIG_HAL_USE_SYSTICK + endif +endif + +$(info $$DEFINES [${DEFINES}]) diff --git a/firmware-template-gd32/calculate_unused_ram.sh b/firmware-template-gd32/calculate_unused_ram.sh deleted file mode 100755 index fe1be4c..0000000 --- a/firmware-template-gd32/calculate_unused_ram.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -if [ $# -lt 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -size_file="$1" -linker_script="$2" - -used_stack=$(grep ".stack" "$size_file" | awk '{print $2}') -used_tcmsram=$(grep ".tcmsram" "$size_file" | awk '{print $2}') -used_heap=$(grep ".heap" "$size_file" | awk '{print $2}') - -total_tcmsram=$(grep "TCMSRAM (rw)" "$linker_script" | awk '{print $NF}' | sed 's/K$//' | awk '{printf "%d", $0 * 1024}') -unused_tcmsram=$(( $(echo $total_tcmsram) - $(echo $used_stack) - $(echo $used_tcmsram) - $(echo $used_heap) )) - -used_data=$(grep '.data' "$size_file" | tail -n 1 | awk '{print $2}') -used_bss=$(grep ".bss" "$size_file" | awk '{print $2}') - -total_ram=$(grep "RAM (xrw)" "$linker_script" | awk '{print $NF}' | sed 's/K$//' | awk '{printf "%d", $0 * 1024}') -unused_ram=$(( $(echo $total_ram) - $(echo $used_data) )) - -used_ramadd=$(grep ".ramadd" "$size_file" | awk '{print $2}') - -total_ramadd=$(grep "RAMADD (xrw)" "$linker_script" | awk '{print $NF}' | sed 's/K$//' | awk '{printf "%d", $0 * 1024}') -unused_ramadd=$(( $(echo $total_ramadd) - $(echo $used_ramadd) - $(echo $used_bss))) - -cat $1 -echo "TCMSRAM $total_tcmsram bytes, Unused TCMSRAM: $unused_tcmsram bytes" -echo "RAM $total_ram bytes, Unused: $unused_ram bytes" -echo "RAMADD $total_ramadd bytes, Unused: $unused_ramadd bytes" -echo \ No newline at end of file diff --git a/firmware-template-gd32/gd32f450vi_flash.ld b/firmware-template-gd32/gd32f450vi_flash.ld index afb2f3f..5f80532 100644 --- a/firmware-template-gd32/gd32f450vi_flash.ld +++ b/firmware-template-gd32/gd32f450vi_flash.ld @@ -11,8 +11,8 @@ ENTRY(Reset_Handler) SECTIONS { - __heap_size = DEFINED(__heap_size) ? __heap_size : 1K; - __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + __heap_size = DEFINED(__heap_size) ? __heap_size : 4K; + __stack_size = DEFINED(__stack_size) ? __stack_size : 4K; .vectors : { @@ -34,47 +34,42 @@ SECTIONS *(.glue_7t) *(.eh_frame) KEEP (*(.init)) - KEEP (*(.fini)) + KEEP (*(.fini)) . = ALIGN(4); _etext = .; - - . = ALIGN(8); - + } >FLASH + + .rodata : + { + . = ALIGN(4); + *(.rodata) + *(.rodata*) + . = ALIGN(4); + } >FLASH + + .preinit_array : + { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); - + } >FLASH + + .init_array : + { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); - + } >FLASH + + .fini_array : + { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH - .rodata : - { - . = ALIGN(4); - *(.rodata) - *(.rodata*) - . = ALIGN(4); - } >FLASH - - _sidata = LOADADDR(.data); - .data : - { - . = ALIGN(4); - _sdata = .; - *(.data) - *(.data*) - . = ALIGN(4); - _edata = .; - } >RAM AT> FLASH - .stack : { . = ALIGN(4); @@ -105,6 +100,17 @@ SECTIONS . = ALIGN(4); } >TCMSRAM + _sidata = LOADADDR(.data); + .data : + { + . = ALIGN(4); + _sdata = .; + *(.data) + *(.data*) + . = ALIGN(4); + _edata = .; + } >RAM AT> FLASH + . = ALIGN(4); .bss : { @@ -118,7 +124,7 @@ SECTIONS __bss_end__ = _ebss; } >RAMADD - . = ALIGN(8); + . = ALIGN(8); PROVIDE ( end = _ebss ); PROVIDE ( _end = _ebss ); @@ -148,4 +154,4 @@ SECTIONS } } -GROUP(libgcc.a libc.a) \ No newline at end of file +GROUP(libgcc.a) diff --git a/firmware-template-gd32/hardfault_handler.c b/firmware-template-gd32/hardfault_handler.c new file mode 100644 index 0000000..039d1f9 --- /dev/null +++ b/firmware-template-gd32/hardfault_handler.c @@ -0,0 +1,77 @@ +/* + * hardfault_handler.c + */ +/** + * Using Cortex-M3/M4/M7 Fault Exceptions + * MDK Tutorial + * AN209, Summer 2017, V 5.0 + */ + +#include + +#include "gd32.h" + +void HardFault_Handler() { + __asm volatile( + "TST LR, #4\n" + "ITE EQ\n" + "MRSEQ R0, MSP\n" + "MRSNE R0, PSP\n" + "MOV R1, LR\n" + "B hardfault_handler\n" + ); +} + +void hardfault_handler(unsigned long *hardfault_args, unsigned int lr_value) { + unsigned long stacked_r0; + unsigned long stacked_r1; + unsigned long stacked_r2; + unsigned long stacked_r3; + unsigned long stacked_r12; + unsigned long stacked_lr; + unsigned long stacked_pc; + unsigned long stacked_psr; + unsigned long cfsr; + unsigned long bus_fault_address; + unsigned long memmanage_fault_address; + + bus_fault_address = SCB->BFAR; + memmanage_fault_address = SCB->MMFAR; + cfsr = SCB->CFSR; + + stacked_r0 = ((unsigned long) hardfault_args[0]); + stacked_r1 = ((unsigned long) hardfault_args[1]); + stacked_r2 = ((unsigned long) hardfault_args[2]); + stacked_r3 = ((unsigned long) hardfault_args[3]); + stacked_r12 = ((unsigned long) hardfault_args[4]); + stacked_lr = ((unsigned long) hardfault_args[5]); + stacked_pc = ((unsigned long) hardfault_args[6]); + stacked_psr = ((unsigned long) hardfault_args[7]); + + printf("[HardFault]\n"); + printf("- Stack frame:\n"); + printf(" R0 = %x\n", (unsigned int) stacked_r0); + printf(" R1 = %x\n", (unsigned int) stacked_r1); + printf(" R2 = %x\n", (unsigned int) stacked_r2); + printf(" R3 = %x\n", (unsigned int) stacked_r3); + printf(" R12 = %x\n", (unsigned int) stacked_r12); + printf(" LR = %x\n", (unsigned int) stacked_lr); + printf(" PC = %x\n", (unsigned int) stacked_pc); + printf(" PSR = %x\n", (unsigned int) stacked_psr); + printf("- FSR/FAR:\n"); + printf(" CFSR = %x\n", (unsigned int) cfsr); + printf(" HFSR = %x\n", (unsigned int) SCB->HFSR); + printf(" DFSR = %x\n", (unsigned int) SCB->DFSR); + printf(" AFSR = %x\n", (unsigned int) SCB->AFSR); + if (cfsr & 0x0080) { + printf(" MMFAR = %x\n", (unsigned int) memmanage_fault_address); + } + if (cfsr & 0x8000) { + printf(" BFAR = %x\n", (unsigned int) bus_fault_address); + } + printf("- Misc\n"); + printf(" LR/EXC_RETURN= %x\n", lr_value); + + while (1) + ; +} diff --git a/firmware-template-gd32/lib/Rules.mk b/firmware-template-gd32/lib/Rules.mk index 95f584b..f971021 100644 --- a/firmware-template-gd32/lib/Rules.mk +++ b/firmware-template-gd32/lib/Rules.mk @@ -1,3 +1,6 @@ +$(info "lib/Rules.mk") +$(info $$MAKE_FLAGS [${MAKE_FLAGS}]) + PREFIX ?= arm-none-eabi- CC = $(PREFIX)gcc @@ -7,40 +10,36 @@ LD = $(PREFIX)ld AR = $(PREFIX)ar BOARD?=BOARD_GD32F450VI -ENET_PHY?=DP83848 -FAMILY?=gd32f4xx -MCU?=gd32f450 +ENET_PHY?=RTL8201F -MCU_UC:=$(shell echo $(MCU_UC) | tr a-w A-W) -FAMILY:=$(shell echo $(FAMILY) | tr A-Z a-z) -FAMILY_UC=$(shell echo $(FAMILY) | tr a-w A-W) +$(info $$BOARD [${BOARD}]) +$(info $$ENET_PHY [${ENET_PHY}]) -$(info $$FAMILY_UC [${MCU_UC}]) -$(info $$FAMILY [${FAMILY}]) -$(info $$FAMILY_UC [${FAMILY_UC}]) +SRCDIR=src src/gd32 $(EXTRA_SRCDIR) -SRCDIR = src src/gd32 $(EXTRA_SRCDIR) +DEFINES:=$(addprefix -D,$(DEFINES)) +DEFINES+=-D_TIME_STAMP_YEAR_=$(shell date +"%Y") -D_TIME_STAMP_MONTH_=$(shell date +"%-m") -D_TIME_STAMP_DAY_=$(shell date +"%-d") +include ../firmware-template-gd32/Board.mk +include ../firmware-template-gd32/Mcu.mk include ../firmware-template-gd32/Includes.mk +include ../firmware-template-gd32/Validate.mk -DEFINES:=$(addprefix -D,$(DEFINES)) -DEFINES+=-D_TIME_STAMP_YEAR_=$(shell date +"%Y") -D_TIME_STAMP_MONTH_=$(shell date +"%-m") -D_TIME_STAMP_DAY_=$(shell date +"%-d") +INCLUDES+=-I../lib-configstore/include -I../lib-display/include -I../lib-flash/include -I../lib-flashcode/include -I../lib-hal/include -I../lib-network/include -COPS=-DBARE_METAL -DGD32 -DGD32F450 -D$(BOARD) -DPHY_TYPE=$(ENET_PHY) -COPS+=$(DEFINES) $(MAKE_FLAGS) $(INCLUDES) -COPS+=-Os -mcpu=cortex-m4 -mthumb -g -mfloat-abi=hard -fsingle-precision-constant -mfpu=fpv4-sp-d16 -COPS+=-DARM_MATH_CM4 -D__FPU_PRESENT=1 -COPS+=-nostartfiles -ffreestanding -nostdlib +COPS=-DGD32 -D$(FAMILY_UCA) -D$(LINE_UC) -D$(MCU) -D$(BOARD) -DPHY_TYPE=$(ENET_PHY) +COPS+=$(strip $(DEFINES)) $(MAKE_FLAGS) $(INCLUDES) +COPS+=$(strip $(ARMOPS) $(CMSISOPS)) +COPS+=-Os -nostartfiles -ffreestanding -nostdlib +COPS+=-fstack-usage COPS+=-ffunction-sections -fdata-sections +COPS+=-Wall -Werror -Wpedantic -Wextra -Wunused -Wsign-conversion -Wconversion -Wduplicated-cond -Wlogical-op -CPPOPS=-std=c++11 +CPPOPS=-std=c++20 CPPOPS+=-Wnon-virtual-dtor -Woverloaded-virtual -Wnull-dereference -fno-rtti -fno-exceptions -fno-unwind-tables -#CPPOPS+=-Wuseless-cast -Wold-style-cast +CPPOPS+=-Wuseless-cast -Wold-style-cast CPPOPS+=-fno-threadsafe-statics -CURR_DIR:=$(notdir $(patsubst %/,%,$(CURDIR))) -LIB_NAME:=$(patsubst lib-%,%,$(CURR_DIR)) - BUILD=build_gd32/ BUILD_DIRS:=$(addprefix build_gd32/,$(SRCDIR)) $(info $$BUILD_DIRS [${BUILD_DIRS}]) @@ -49,22 +48,31 @@ C_OBJECTS=$(foreach sdir,$(SRCDIR),$(patsubst $(sdir)/%.c,$(BUILD)$(sdir)/%.o,$( CPP_OBJECTS=$(foreach sdir,$(SRCDIR),$(patsubst $(sdir)/%.cpp,$(BUILD)$(sdir)/%.o,$(wildcard $(sdir)/*.cpp))) ASM_OBJECTS=$(foreach sdir,$(SRCDIR),$(patsubst $(sdir)/%.S,$(BUILD)$(sdir)/%.o,$(wildcard $(sdir)/*.S))) -OBJECTS:=$(ASM_OBJECTS) $(C_OBJECTS) $(CPP_OBJECTS) +EXTRA_C_OBJECTS=$(patsubst %.c,$(BUILD)%.o,$(EXTRA_C_SOURCE_FILES)) +EXTRA_C_DIRECTORIES=$(shell dirname $(EXTRA_C_SOURCE_FILES)) +EXTRA_BUILD_DIRS:=$(addsuffix $(EXTRA_C_DIRECTORIES), $(BUILD)) -TARGET=lib_gd32/lib$(LIB_NAME).a -$(info $$TARGET [${TARGET}]) +OBJECTS:=$(strip $(ASM_OBJECTS) $(C_OBJECTS) $(CPP_OBJECTS) $(EXTRA_C_OBJECTS)) -LIST = lib.list +CURR_DIR:=$(notdir $(patsubst %/,%,$(CURDIR))) +LIB_NAME:=$(patsubst lib-%,%,$(CURR_DIR)) +TARGET=lib_gd32/lib$(LIB_NAME).a + +$(info $$DEFINES [${DEFINES}]) +$(info $$MAKE_FLAGS [${MAKE_FLAGS}]) +$(info $$OBJECTS [${OBJECTS}]) +$(info $$TARGET [${TARGET}]) define compile-objects +$(info $1) $(BUILD)$1/%.o: $1/%.c $(CC) $(COPS) -c $$< -o $$@ $(BUILD)$1/%.o: $1/%.cpp - $(CPP) $(COPS) $(CPPOPS) -c $$< -o $$@ + $(CPP) $(COPS) $(CPPOPS) -c $$< -o $$@ $(BUILD)$1/%.o: $1/%.S - $(CC) $(COPS) -D__ASSEMBLY__ -c $$< -o $$@ + $(CC) $(COPS) -D__ASSEMBLY__ -c $$< -o $$@ endef all : builddirs $(TARGET) @@ -73,18 +81,22 @@ all : builddirs $(TARGET) builddirs: mkdir -p $(BUILD_DIRS) + mkdir -p $(EXTRA_BUILD_DIRS) mkdir -p lib_gd32 clean: rm -rf build_gd32 rm -rf lib_gd32 +$(BUILD)%.o: %.c + $(CC) $(COPS) -c $< -o $@ + $(BUILD_DIRS) : mkdir -p $(BUILD_DIRS) mkdir -p lib_gd32 $(TARGET): Makefile.GD32 $(OBJECTS) $(AR) -r $(TARGET) $(OBJECTS) - $(PREFIX)objdump -d $(TARGET) | $(PREFIX)c++filt > lib_gd32/$(LIST) + $(PREFIX)objdump -d $(TARGET) | $(PREFIX)c++filt > lib_gd32/lib.list $(foreach bdir,$(SRCDIR),$(eval $(call compile-objects,$(bdir)))) \ No newline at end of file diff --git a/firmware-template-gd32/startup_gd32f450.S b/firmware-template-gd32/startup_gd32f450.S index 09ba79a..b19e53a 100644 --- a/firmware-template-gd32/startup_gd32f450.S +++ b/firmware-template-gd32/startup_gd32f450.S @@ -1,3 +1,28 @@ +/** + * @file startup_gd32f450.S + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + .syntax unified .cpu cortex-m4 .fpu softvfp @@ -5,61 +30,70 @@ .global Default_Handler -.word _sidata -.word _sdata -.word _edata -.word _sbss -.word _ebss +/* Necessary symbols defined in linker script to initialize data */ +.word _sdata +.word _sidata +.word _edata +.word _sbss +.word _ebss -.section .text.Reset_Handler +.section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: - movs r1, #0 - b DataInit - +/* Copy .data section from FLASH to RAM */ CopyData: - ldr r3, =_sidata - ldr r3, [r3, r1] - str r3, [r0, r1] - adds r1, r1, #4 - -DataInit: - ldr r0, =_sdata - ldr r3, =_edata - adds r2, r0, r1 - cmp r2, r3 - bcc CopyData - ldr r2, =_sbss - b Zerobss -FillZerobss: - movs r3, #0 - str r3, [r2], #4 - -Zerobss: - ldr r3, = _ebss - cmp r2, r3 - bcc FillZerobss + ldr r1, =_sdata /* Load the start address of .data section (RAM) into r1 */ + ldr r2, =_sidata /* Load the start address of .data section (FLASH) into r2 */ + ldr r3, =_edata /* Load the end address of .data section (RAM) into r3 */ + subs r3, r3, r1 /* Calculate the size of .data section by subtracting start from end */ + beq ZeroBSS /* If size is zero, jump to ZeroBSS */ +CopyDataLoop: + ldrb r4, [r2], #1 /* Load a byte from Flash (source), post-increment r2 by 1 */ + strb r4, [r1], #1 /* Store the byte to RAM (destination), post-increment r1 by 1 */ + subs r3, r3, #1 /* Decrement the remaining byte count by 1 */ + bgt CopyDataLoop /* If there are still bytes left, continue looping */ +/* Initialize .bss section to zero */ +ZeroBSS: + ldr r2, =_sbss /* Load the start address of the .bss section */ + ldr r3, =_ebss /* Load the end address of the .bss section */ + sub r3, r3, r2 /* Calculate bytes count (r3 = (end - start) */ + mov r4, #0 /* Load zero into r4 */ +ZeroBSSLoop: + str r4, [r2], #4 /* Store zero to memory location, increment address */ + subs r3, r3, #4 /* Subtract 4 bytes from the remaining byte count */ + bgt ZeroBSSLoop /* If there are still bytes left, continue looping */ +/* Call stack_debug_init function if in debug mode */ #if defined (DEBUG_STACK) - bl stack_debug_init + bl stack_debug_init /* Branch to stack_debug_init if DEBUG_STACK is defined */ #endif +/* Call SystemInit function to perform system-specific initialization */ bl SystemInit +/* Call static constructors to initialize global objects */ + bl __libc_init_array +/* Call the main function to start the application */ bl main +/* Return from main (in case main returns) */ bx lr +/* NOP to align the code (optional) */ + nop /* No operation; used for code alignment and readability */ + .size Reset_Handler, .-Reset_Handler .section .text.Default_Handler,"ax",%progbits + Default_Handler: Infinite_Loop: b Infinite_Loop - .size Default_Handler, .-Default_Handler - .section .vectors,"a",%progbits - .global __gVectors +.size Default_Handler, .-Default_Handler + +.section .vectors,"a",%progbits +.global __gVectors __gVectors: - .word _sp /* Top of Stack */ + .word _sp /* Top of Stack */ .word Reset_Handler /* Reset Handler */ .word NMI_Handler /* NMI Handler */ .word HardFault_Handler /* Hard Fault Handler */ @@ -75,8 +109,7 @@ __gVectors: .word 0 /* Reserved */ .word PendSV_Handler /* PendSV Handler */ .word SysTick_Handler /* SysTick Handler */ - - /* external interrupts handler */ + /* External Interrupts */ .word WWDGT_IRQHandler /* 16:Window Watchdog Timer */ .word LVD_IRQHandler /* 17:LVD through EXTI Line detect */ .word TAMPER_STAMP_IRQHandler /* 18:Tamper and TimeStamp through EXTI Line detect */ @@ -171,6 +204,12 @@ __gVectors: .size __gVectors, . - __gVectors +/******************************************************************************* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +*******************************************************************************/ + .weak NMI_Handler .thumb_set NMI_Handler,Default_Handler diff --git a/include/cstring b/include/cstring index 998d93d..b32bea0 100644 --- a/include/cstring +++ b/include/cstring @@ -2,7 +2,7 @@ * @file cstring * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +26,37 @@ #ifndef CSTRING_ #define CSTRING_ -#ifdef __cplusplus -# include -#endif +#include + +// Get rid of those macros defined in in lieu of real functions. +#undef memcmp +#undef memcpy +#undef memmove +#undef memset +#undef strchr +#undef strcmp +#undef strcpy +#undef strerror +#undef strlen +#undef strncmp +#undef strncpy +#undef strstr +#undef strtok + +namespace std { +using ::memcmp; +using ::memcpy; +using ::memmove; +using ::memset; +using ::strcmp; +using ::strcpy; +using ::strerror; +using ::strlen; +using ::strncmp; +using ::strncpy; +using ::strtok; +using ::strchr; +using ::strstr; +} #endif /* CSTRING_ */ diff --git a/include/dirent.h b/include/dirent.h index 70e0160..772c3b9 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -2,7 +2,7 @@ * @file dirent.h * */ -/* Copyright (C) 2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2020-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,7 @@ #include -#if !defined (_FATFS) +#if !defined (FF_DEFINED) typedef void *DIR; #endif diff --git a/include/stdio.h b/include/stdio.h index 364bf88..86e4741 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -2,7 +2,7 @@ * @file stdio.h * */ -/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,10 +28,29 @@ #include #include - -#define EOF -1 - -typedef void *FILE; +#include + +#define EOF (-1) + +typedef struct __sFILE { + void *udata; +#define __SLBF 0x0001 /* line buffered */ +#define __SNBF 0x0002 /* unbuffered */ +#define __SRD 0x0004 /* OK to read */ +#define __SWR 0x0008 /* OK to write */ + /* RD and WR are never simultaneously asserted */ +#define __SRW 0x0010 /* open for reading & writing */ +#define __SEOF 0x0020 /* found EOF */ +#define __SERR 0x0040 /* found error */ + uint8_t flags; +} FILE; + +#if defined(CONFIG_POSIX_ENABLE_STDIN) +#error Not supported +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; +#endif #ifndef SEEK_SET #define SEEK_SET 0 /* set file offset to offset */ @@ -49,36 +68,40 @@ typedef void *FILE; extern "C" { #endif -extern int puts(const char *s); -extern int putchar(int c); +int puts(const char *s); +int putchar(int c); + +int fileno(FILE *stream); -extern FILE *fopen(const char *path, const char *mode); -extern int fclose(FILE *stream); +FILE *fopen(const char *path, const char *mode); +int fclose(FILE *stream); -extern int fgetc(FILE *stream); +int fgetc(FILE *stream); +int fputc(int c, FILE *stream); -extern char *fgets(char *s, int size, FILE *stream); -extern int fputs(const char *s, FILE *stream); +char *fgets(char *s, int size, FILE *stream); +int fputs(const char *s, FILE *stream); -extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); -extern size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); -extern int fseek(FILE *stream, long offset, int whence); +int fseek(FILE *stream, long offset, int whence); -extern long ftell(FILE *stream); +long ftell(FILE *stream); -extern void clearerr(FILE *stream); -extern int ferror(FILE *stream); +void clearerr(FILE *stream); +int ferror(FILE *stream); +int feof(FILE *stream); -extern int printf(const char *format, ...); +int printf(const char *format, ...); -extern int sprintf(char *str, const char *format, ...); -extern int snprintf(char *str, size_t size, const char *format, ...); +int sprintf(char *str, const char *format, ...); +int snprintf(char *str, size_t size, const char *format, ...); -extern int vprintf(const char *format, va_list ap); -extern int vsnprintf(char *str, size_t size, const char *format, va_list); +int vprintf(const char *format, va_list ap); +int vsnprintf(char *str, size_t size, const char *format, va_list); -extern void perror(const char *s); +void perror(const char *s); #ifdef __cplusplus } diff --git a/include/string.h b/include/string.h index fdbdbb4..9763a14 100644 --- a/include/string.h +++ b/include/string.h @@ -35,6 +35,7 @@ extern "C" { extern char *strerror(int errnum); extern char *strtok(char *str, const char *delim); +extern char *strstr(const char *string, const char *substring); inline int memcmp(const void *s1, const void *s2, size_t n) { unsigned char u1, u2; @@ -193,6 +194,20 @@ inline char *strcat(char *s1, const char *s2) { return s1; } +inline char *strchr(const char *p, int ch) { + char c = (char) ch; + + for (;; ++p) { + if (*p == c) { + return (char *)p; + } + if (*p == '\0') { + return NULL; + } + } + /* NOTREACHED */ +} + #ifdef __cplusplus } #endif diff --git a/include/time.h b/include/time.h index d77b3b6..bee8d35 100644 --- a/include/time.h +++ b/include/time.h @@ -2,7 +2,7 @@ * @file time.h * */ -/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -61,6 +61,7 @@ extern "C" { extern time_t time(time_t *t); extern time_t mktime(struct tm *tm); +extern struct tm *gmtime(const time_t *timep); extern struct tm *localtime(const time_t *timep); extern char *asctime(const struct tm *tm); diff --git a/lib-c++/.cproject b/lib-c++/.cproject deleted file mode 100644 index 3021b34..0000000 --- a/lib-c++/.cproject +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-c++/.settings/language.settings.xml b/lib-c++/.settings/language.settings.xml deleted file mode 100644 index 16a7513..0000000 --- a/lib-c++/.settings/language.settings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-c++/Makefile.GD32 b/lib-c++/Makefile.GD32 deleted file mode 100644 index ff29a8d..0000000 --- a/lib-c++/Makefile.GD32 +++ /dev/null @@ -1,2 +0,0 @@ - -include ../firmware-template-gd32/lib/Rules.mk \ No newline at end of file diff --git a/lib-c/.cproject b/lib-c/.cproject deleted file mode 100644 index 949c7f2..0000000 --- a/lib-c/.cproject +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-c/.settings/language.settings.xml b/lib-c/.settings/language.settings.xml deleted file mode 100644 index 1dd8a87..0000000 --- a/lib-c/.settings/language.settings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-c/.settings/org.eclipse.cdt.core.prefs b/lib-c/.settings/org.eclipse.cdt.core.prefs deleted file mode 100644 index c8ec5df..0000000 --- a/lib-c/.settings/org.eclipse.cdt.core.prefs +++ /dev/null @@ -1,6 +0,0 @@ -doxygen/doxygen_new_line_after_brief=true -doxygen/doxygen_use_brief_tag=false -doxygen/doxygen_use_javadoc_tags=true -doxygen/doxygen_use_pre_tag=false -doxygen/doxygen_use_structural_commands=false -eclipse.preferences.version=1 diff --git a/lib-c/Makefile.GD32 b/lib-c/Makefile.GD32 deleted file mode 100644 index b54ecb2..0000000 --- a/lib-c/Makefile.GD32 +++ /dev/null @@ -1,3 +0,0 @@ -#DEFINES=MEM_DEBUG - -include ../firmware-template-gd32/lib/Rules.mk \ No newline at end of file diff --git a/lib-clib/.cproject b/lib-clib/.cproject new file mode 100644 index 0000000..172639c --- /dev/null +++ b/lib-clib/.cproject @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib-c++/.project b/lib-clib/.project similarity index 97% rename from lib-c++/.project rename to lib-clib/.project index cabc78a..47d0f02 100644 --- a/lib-c++/.project +++ b/lib-clib/.project @@ -1,6 +1,6 @@ - lib-c++ + lib-clib diff --git a/lib-clib/.settings/language.settings.xml b/lib-clib/.settings/language.settings.xml new file mode 100755 index 0000000..9f1cbad --- /dev/null +++ b/lib-clib/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib-c/.settings/org.eclipse.core.resources.prefs b/lib-clib/.settings/org.eclipse.core.resources.prefs old mode 100644 new mode 100755 similarity index 100% rename from lib-c/.settings/org.eclipse.core.resources.prefs rename to lib-clib/.settings/org.eclipse.core.resources.prefs diff --git a/lib-clib/Makefile.GD32 b/lib-clib/Makefile.GD32 new file mode 100644 index 0000000..0502e1a --- /dev/null +++ b/lib-clib/Makefile.GD32 @@ -0,0 +1,25 @@ +DEFINES=NDEBUG + +EXTRA_INCLUDES= + +EXTRA_SRCDIR= + +ifneq ($(MAKE_FLAGS),) + ifeq ($(findstring CONFIG_ENET_ENABLE_PTP,$(MAKE_FLAGS)), CONFIG_ENET_ENABLE_PTP) + EXTRA_SRCDIR+=src/gd32/time_ptp + else + ifeq ($(findstring CONFIG_TIME_USE_TIMER,$(MAKE_FLAGS)), CONFIG_TIME_USE_TIMER) + EXTRA_SRCDIR+=src/gd32/time_timer + else + EXTRA_SRCDIR+=src/gd32/time_systick + endif + endif +else + EXTRA_SRCDIR+=src/gd32/time_systick + + EXTRA_SRCDIR+=src/gd32/time_timer + DEFINES+=CONFIG_TIME_USE_TIMER +endif + +include Rules.mk +include ../firmware-template-gd32/lib/Rules.mk \ No newline at end of file diff --git a/lib-clib/Rules.mk b/lib-clib/Rules.mk new file mode 100755 index 0000000..821b5db --- /dev/null +++ b/lib-clib/Rules.mk @@ -0,0 +1,2 @@ + +EXTRA_SRCDIR+=src/c++ \ No newline at end of file diff --git a/lib-clib/src/abort.c b/lib-clib/src/abort.c new file mode 100755 index 0000000..7680b69 --- /dev/null +++ b/lib-clib/src/abort.c @@ -0,0 +1,15 @@ +/* + * abort.c + */ + + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include + +void abort(void) { + assert(0); + for(;;); +} diff --git a/lib-c/src/asctime.c b/lib-clib/src/asctime.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/asctime.c rename to lib-clib/src/asctime.c diff --git a/lib-clib/src/c++/cxa_atexit.cpp b/lib-clib/src/c++/cxa_atexit.cpp new file mode 100755 index 0000000..cae8031 --- /dev/null +++ b/lib-clib/src/c++/cxa_atexit.cpp @@ -0,0 +1,26 @@ +/* + * cxa_atexit.cpp + */ + +#include + +typedef void (*exitfunc_t)(); + +static exitfunc_t atexit_funcs[32]; +static size_t atexit_count = 0; + +extern "C" int __cxa_atexit(exitfunc_t func, [[maybe_unused]] void *arg, [[maybe_unused]] void *dso_handle) { + if (atexit_count >= sizeof(atexit_funcs) / sizeof(atexit_funcs[0])) + return -1; + + atexit_funcs[atexit_count++] = func; + return 0; // Success +} + +extern "C" void __call_atexit_funcs() { + for (size_t i = atexit_count; i > 0; --i) { + exitfunc_t func = atexit_funcs[i - 1]; + if (func) + func(); + } +} diff --git a/lib-c++/src/delete.cpp b/lib-clib/src/c++/delete.cpp old mode 100644 new mode 100755 similarity index 78% rename from lib-c++/src/delete.cpp rename to lib-clib/src/c++/delete.cpp index 4f5019c..72c4aa9 --- a/lib-c++/src/delete.cpp +++ b/lib-clib/src/c++/delete.cpp @@ -2,7 +2,7 @@ * @file delete.cpp * */ -/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,8 @@ * THE SOFTWARE. */ -#include +#include +#include void operator delete(void *p) { free(p); @@ -32,3 +33,15 @@ void operator delete(void *p) { void operator delete[](void *p) { free(p); } + +/* + * C++14 and above + */ + +void operator delete(void *p, [[maybe_unused]] std::size_t size) noexcept { + free(p); +} + +void operator delete[](void *p, [[maybe_unused]]std::size_t size) noexcept { + free(p); +} diff --git a/lib-clib/src/c++/dso_handle.cpp b/lib-clib/src/c++/dso_handle.cpp new file mode 100755 index 0000000..2b06c2e --- /dev/null +++ b/lib-clib/src/c++/dso_handle.cpp @@ -0,0 +1,33 @@ +/** + * @file dso_handle.cpp + * + */ +/* Copyright (C) 2023 by Arjan van Vught mailto:info@info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +//extern "C" int __aeabi_atexit(void *object, void (*destructor)(void *), void *dso_handle) { +// static_cast(object); +// static_cast(destructor); +// static_cast(dso_handle); +// return 0; +//} + +void *__dso_handle = nullptr; diff --git a/lib-clib/src/c++/impure_prt.cpp b/lib-clib/src/c++/impure_prt.cpp new file mode 100755 index 0000000..98bc95e --- /dev/null +++ b/lib-clib/src/c++/impure_prt.cpp @@ -0,0 +1,11 @@ +/* + * impure_prt.cpp + */ + +typedef struct _reent { + int _errno; // Placeholder for the actual contents of _reent +} _reent; + +// Define the global _impure_ptr. Normally points to reentrant data. +static struct _reent _reent_data = {0}; +struct _reent *_impure_ptr = &_reent_data; diff --git a/lib-c++/src/new.cpp b/lib-clib/src/c++/new.cpp old mode 100644 new mode 100755 similarity index 92% rename from lib-c++/src/new.cpp rename to lib-clib/src/c++/new.cpp index 6cf0eb0..64b61cc --- a/lib-c++/src/new.cpp +++ b/lib-clib/src/c++/new.cpp @@ -2,7 +2,7 @@ * @file new.cpp * */ -/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ * THE SOFTWARE. */ -#include +#include void *operator new(unsigned size) { return malloc(size); diff --git a/lib-c++/src/purecall.cpp b/lib-clib/src/c++/purecall.cpp old mode 100644 new mode 100755 similarity index 94% rename from lib-c++/src/purecall.cpp rename to lib-clib/src/c++/purecall.cpp index b6c1dcb..d4ff1c3 --- a/lib-c++/src/purecall.cpp +++ b/lib-clib/src/c++/purecall.cpp @@ -2,7 +2,7 @@ * @file purecall.cpp * */ -/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-network/src/net/ntp_internal.h b/lib-clib/src/errno.c old mode 100644 new mode 100755 similarity index 83% rename from lib-network/src/net/ntp_internal.h rename to lib-clib/src/errno.c index 328dafa..d316613 --- a/lib-network/src/net/ntp_internal.h +++ b/lib-clib/src/errno.c @@ -1,8 +1,8 @@ /** - * @file ntp_internal.h + * @file errno.c * */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2020 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,11 +23,4 @@ * THE SOFTWARE. */ -#ifndef NTP_INTERNAL_H_ -#define NTP_INTERNAL_H_ - -enum { - NTP_PORT_SERVER = 123 -}; - -#endif /* NTP_INTERNAL_H_ */ +int errno = 0; diff --git a/lib-c/src/assert.c b/lib-clib/src/gd32/assert.c similarity index 100% rename from lib-c/src/assert.c rename to lib-clib/src/gd32/assert.c diff --git a/lib-clib/src/gd32/malloc.h b/lib-clib/src/gd32/malloc.h new file mode 100755 index 0000000..7a4109a --- /dev/null +++ b/lib-clib/src/gd32/malloc.h @@ -0,0 +1,31 @@ +/** + * @file malloc.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GD32_MALLOC_H_ +#define GD32_MALLOC_H_ + +static struct block_bucket s_block_bucket[] __attribute__((aligned(4))) = {{0x10, 0}, {0x20, 0}, {0x40, 0}, {0x60, 0}, {0x80,0}, {0x100,0}, {0x140,0}, {0x180,0}, {0x200,0}, {0x300,0}, {0x400,0}, {0x500,0}, {0,0}}; + +#endif /* GD32_MALLOC_H_ */ diff --git a/lib-clib/src/gd32/time_ptp/time.cpp b/lib-clib/src/gd32/time_ptp/time.cpp new file mode 100644 index 0000000..a418f74 --- /dev/null +++ b/lib-clib/src/gd32/time_ptp/time.cpp @@ -0,0 +1,99 @@ +/** + * @file time.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma GCC push_options +#pragma GCC optimize ("O2") + +#include +#include +#include +#include + +#include "gd32.h" +#include "gd32_ptp.h" + +#if defined (GD32H7XX) +# define enet_ptp_timestamp_function_config(x) enet_ptp_timestamp_function_config(ENETx, x) +# define enet_ptp_timestamp_update_config(x,y,z) enet_ptp_timestamp_update_config(ENETx, x, y, z) +# define enet_ptp_system_time_get(x) enet_ptp_system_time_get(ENETx, x) +#endif + +extern "C" { +/* + * number of seconds and microseconds since the Epoch, + * 1970-01-01 00:00:00 +0000 (UTC). + */ + +int gettimeofday(struct timeval *tv, [[maybe_unused]] struct timezone *tz) { + assert(tv != 0); + + enet_ptp_systime_struct systime; + enet_ptp_system_time_get(&systime); + + tv->tv_sec = systime.second; + +#if !defined (GD32F4XX) + const auto nNanoSecond = systime.nanosecond; +#else + const auto nNanoSecond = gd32::ptp_subsecond_2_nanosecond(systime.subsecond); +#endif + + tv->tv_usec = nNanoSecond / 1000U; + + return 0; +} + +int settimeofday(const struct timeval *tv, [[maybe_unused]] const struct timezone *tz) { + assert(tv != 0); + + const uint32_t nSign = ENET_PTP_ADD_TO_TIME; + const uint32_t nSecond = tv->tv_sec; + const uint32_t nNanoSecond = tv->tv_usec * 1000U; + const auto nSubSecond = gd32::ptp_nanosecond_2_subsecond(nNanoSecond); + + enet_ptp_timestamp_update_config(nSign, nSecond, nSubSecond); + + if (SUCCESS == enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_INIT)) { + return 0; + } + + return -1; +} + +/* + * time() returns the time as the number of seconds since the Epoch, + 1970-01-01 00:00:00 +0000 (UTC). + */ +time_t time(time_t *__timer) { + struct timeval tv; + gettimeofday(&tv, 0); + + if (__timer != nullptr) { + *__timer = tv.tv_sec; + } + + return tv.tv_sec; +} +} diff --git a/lib-c/src/gd32/time.c b/lib-clib/src/gd32/time_systick/time.cpp old mode 100755 new mode 100644 similarity index 54% rename from lib-c/src/gd32/time.c rename to lib-clib/src/gd32/time_systick/time.cpp index b754cc2..024803b --- a/lib-c/src/gd32/time.c +++ b/lib-clib/src/gd32/time_systick/time.cpp @@ -2,7 +2,7 @@ * @file time.c * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@gd32-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,50 +23,67 @@ * THE SOFTWARE. */ -#include -#include -#include -#include +#pragma GCC push_options +#pragma GCC optimize ("O2") -extern volatile uint32_t s_nSysTickMillis; +#include +#include +#include +#include -static uint32_t set_timer = 0; -static uint64_t s_micros = 0; +extern volatile uint32_t gv_nSysTickMillis; -#define MICROS_SECONDS 1000000 +static uint32_t nPreviousSysTickMillis; +static struct timeval s_tv; +extern "C" { /* * number of seconds and microseconds since the Epoch, * 1970-01-01 00:00:00 +0000 (UTC). */ -int gettimeofday(struct timeval *tv, __attribute__((unused)) struct timezone *tz) { +int gettimeofday(struct timeval *tv, __attribute__((unused)) struct timezone *tz) { assert(tv != 0); - const uint32_t timer = s_nSysTickMillis; // Millis timer + const auto nCurrentSysTickMillis = gv_nSysTickMillis; - uint32_t timer_elapsed; + uint32_t nMillisElapsed; - if (set_timer >= timer) { - timer_elapsed = set_timer - timer; + if (nCurrentSysTickMillis >= nPreviousSysTickMillis) { + nMillisElapsed = nCurrentSysTickMillis - nPreviousSysTickMillis; } else { - timer_elapsed = timer - set_timer; + nMillisElapsed = (UINT32_MAX - nPreviousSysTickMillis) + nCurrentSysTickMillis + 1; } - set_timer = timer; - s_micros += (timer_elapsed * 1000); + nPreviousSysTickMillis = nCurrentSysTickMillis; + + const auto nSeconds = nMillisElapsed / 1000U; + const auto nMicroSeconds = (nMillisElapsed % 1000U) * 1000U; - tv->tv_sec = (time_t)(s_micros / MICROS_SECONDS); - tv->tv_usec = (suseconds_t) (s_micros - ((uint64_t) tv->tv_sec * MICROS_SECONDS)); + s_tv.tv_sec += static_cast(nSeconds); + s_tv.tv_usec += static_cast(nMicroSeconds); + + if (s_tv.tv_usec >= 1000000) { + s_tv.tv_sec++; + s_tv.tv_usec -= 1000000; + } + + tv->tv_sec = s_tv.tv_sec; + tv->tv_usec = s_tv.tv_usec; return 0; } -int settimeofday(const struct timeval *tv, __attribute__((unused)) const struct timezone *tz) { +int settimeofday(const struct timeval *tv, __attribute__((unused)) const struct timezone *tz) { assert(tv != 0); - set_timer = s_nSysTickMillis; - s_micros = ((uint64_t) tv->tv_sec * MICROS_SECONDS) + (uint64_t) tv->tv_usec; + struct timeval g; + gettimeofday(&g, nullptr); + + nPreviousSysTickMillis = gv_nSysTickMillis; + + s_tv.tv_sec = tv->tv_sec; + s_tv.tv_usec = tv->tv_usec; return 0; } @@ -77,11 +94,12 @@ int settimeofday(const struct timeval *tv, __attribute__((unused)) const struct */ time_t time(time_t *__timer) { struct timeval tv; - gettimeofday(&tv, 0); + gettimeofday(&tv, nullptr); - if (__timer != NULL) { + if (__timer != nullptr) { *__timer = tv.tv_sec; } return tv.tv_sec; } +} diff --git a/lib-clib/src/gd32/time_timer/time.cpp b/lib-clib/src/gd32/time_timer/time.cpp new file mode 100644 index 0000000..8782a95 --- /dev/null +++ b/lib-clib/src/gd32/time_timer/time.cpp @@ -0,0 +1,157 @@ +/** + * @file time.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma GCC push_options +#pragma GCC optimize ("O2") + +#include +#include +#include +#include + +#include "gd32.h" + +#if defined(GD32H7XX) +# define TIMERx TIMER16 +# define RCU_TIMERx RCU_TIMER16 +# define TIMERx_IRQn TIMER16_IRQn +#else +# define TIMERx TIMER7 +# define RCU_TIMERx RCU_TIMER7 +# if defined (GD32F10X) || defined (GD32F30X) +# define TIMERx_IRQn TIMER7_IRQn +# else +# define TIMERx_IRQn TIMER7_UP_TIMER12_IRQn +# endif +#endif + +extern struct HwTimersSeconds g_Seconds; + +extern "C" { +#if !defined (CONFIG_ENET_ENABLE_PTP) +# if defined (CONFIG_TIME_USE_TIMER) +# if defined(GD32H7XX) +void TIMER16_IRQHandler() { +# elif defined (GD32F10X) || defined (GD32F30X) +void TIMER7_IRQHandler() { +# else +void TIMER7_UP_TIMER12_IRQHandler() { +# endif + const auto nIntFlag = TIMER_INTF(TIMERx); + + if ((nIntFlag & TIMER_INT_FLAG_UP) == TIMER_INT_FLAG_UP) { + g_Seconds.nTimeval++; + } + + TIMER_INTF(TIMERx) = static_cast(~nIntFlag); +} +# endif +#endif +} + +#if defined(GD32H7XX) +void timer16_config() { +#else +void timer7_config() { +#endif + g_Seconds.nTimeval = 0; + + rcu_periph_clock_enable(RCU_TIMERx); + timer_deinit(TIMERx); + + timer_parameter_struct timer_initpara; + timer_struct_para_init(&timer_initpara); + + timer_initpara.prescaler = TIMER_PSC_10KHZ; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = (10000 - 1); // 1 second + timer_init(TIMERx, &timer_initpara); + + timer_interrupt_flag_clear(TIMERx, ~0); + + timer_interrupt_enable(TIMERx, TIMER_INT_UP); + + NVIC_SetPriority(TIMERx_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); // Lowest priority + NVIC_EnableIRQ(TIMERx_IRQn); + + timer_enable(TIMERx); +} + +extern "C" { +/* + * number of seconds and microseconds since the Epoch, + * 1970-01-01 00:00:00 +0000 (UTC). + */ + +int gettimeofday(struct timeval *tv, __attribute__((unused)) struct timezone *tz) { + assert(tv != 0); + +#if __CORTEX_M == 7 + __DMB(); +#endif + + tv->tv_sec = g_Seconds.nTimeval; + tv->tv_usec = TIMER_CNT(TIMERx) * 100U; + +#if __CORTEX_M == 7 + __ISB(); +#endif + + return 0; +} + +int settimeofday(const struct timeval *tv, __attribute__((unused)) const struct timezone *tz) { + assert(tv != 0); + + // Disable the timer interrupt to prevent it from triggering while we adjust the counter + TIMER_DMAINTEN(TIMERx) &= static_cast(~TIMER_INT_UP); + TIMER_CTL0(TIMERx) &= static_cast(~TIMER_CTL0_CEN); + + g_Seconds.nTimeval = tv->tv_sec; + TIMER_CNT(TIMERx) = (tv->tv_usec / 100U) % 10000; + + TIMER_INTF(TIMERx) = static_cast(~0); + TIMER_DMAINTEN(TIMERx) |= TIMER_INT_UP; + TIMER_CTL0(TIMERx) |= TIMER_CTL0_CEN; + + return 0; +} + +/* + * time() returns the time as the number of seconds since the Epoch, + 1970-01-01 00:00:00 +0000 (UTC). + */ +time_t time(time_t *__timer) { + struct timeval tv; + gettimeofday(&tv, nullptr); + + if (__timer != nullptr) { + *__timer = tv.tv_sec; + } + + return tv.tv_sec; +} +} diff --git a/lib-clib/src/gd32/uuid.cpp b/lib-clib/src/gd32/uuid.cpp new file mode 100644 index 0000000..89f9772 --- /dev/null +++ b/lib-clib/src/gd32/uuid.cpp @@ -0,0 +1,58 @@ +/** + * @file uuid.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of thnDmxDataDirecte Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "gd32.h" + +namespace hal { +typedef union pcast32 { + uuid_t uuid; + uint32_t u32[4]; +} _pcast32; + +void uuid_init(uuid_t out) { + _pcast32 cast; + +#if defined (GD32H7XX) + cast.u32[0] = REG32(0x1FF0F7E8); + cast.u32[1] = REG32(0x1FF0F7EC); + cast.u32[2] = REG32(0x1FF0F7F0); +#elif defined (GD32F4XX) + cast.u32[0] = REG32(0x1FFF7A10); + cast.u32[1] = REG32(0x1FFF7A14); + cast.u32[2] = REG32(0x1FFF7A18); +#else + cast.u32[0] = REG32(0x1FFFF7E8); + cast.u32[1] = REG32(0x1FFFF7EC); + cast.u32[2] = REG32(0x1FFFF7F0); +#endif + cast.u32[3] = cast.u32[0] + cast.u32[1] + cast.u32[2]; + + memcpy(out, cast.uuid, sizeof(uuid_t)); +} +} // namespace hal diff --git a/lib-c/src/inet_aton.c b/lib-clib/src/inet_aton.c old mode 100644 new mode 100755 similarity index 94% rename from lib-c/src/inet_aton.c rename to lib-clib/src/inet_aton.c index 52dbfc3..cc83bb5 --- a/lib-c/src/inet_aton.c +++ b/lib-clib/src/inet_aton.c @@ -25,13 +25,14 @@ #include #include +#include typedef union pcast32 { uint32_t u32; uint8_t u8[4]; } _pcast32; -int inet_aton(const char *cp, uint32_t *ip_address) { +int inet_aton(const char *cp, struct in_addr *ip_address) { const char *b = cp; int i, j, k; _pcast32 cast32; @@ -79,7 +80,7 @@ int inet_aton(const char *cp, uint32_t *ip_address) { cast32.u8[i] = (uint8_t)k; if (ip_address != 0) { - *ip_address = cast32.u32; + ip_address->s_addr = cast32.u32; } return 1; diff --git a/lib-clib/src/init.c b/lib-clib/src/init.c new file mode 100755 index 0000000..647ec7d --- /dev/null +++ b/lib-clib/src/init.c @@ -0,0 +1,23 @@ +/* + * init.c + */ + +#include "stddef.h" + +extern void (*__preinit_array_start []) (void) __attribute__((weak)); +extern void (*__preinit_array_end []) (void) __attribute__((weak)); +extern void (*__init_array_start []) (void) __attribute__((weak)); +extern void (*__init_array_end []) (void) __attribute__((weak)); + +void __libc_init_array(void) { + size_t count; + size_t i; + + count = (size_t)(__preinit_array_end - __preinit_array_start); + for (i = 0; i < count; i++) + __preinit_array_start[i] (); + + count = (size_t)(__init_array_end - __init_array_start); + for (i = 0; i < count; i++) + __init_array_start[i] (); +} diff --git a/lib-clib/src/log.c b/lib-clib/src/log.c new file mode 100755 index 0000000..b8ee6f0 --- /dev/null +++ b/lib-clib/src/log.c @@ -0,0 +1,80 @@ +/** + * @file log.c + * + */ +/* + * Based on http://www.flipcode.com/archives/Fast_log_Function.shtml + * and https://stackoverflow.com/questions/9411823/fast-log2float-x-implementation-c + * + * Reference https://www.doc.ic.ac.uk/~eedwards/compsys/float/nan.html + * and http://steve.hollasch.net/cgindex/coding/ieeefloat.html + */ +/* Copyright (C) 2017-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +typedef union { + float number; + int32_t bits; +} float2bits; + +/* Natural log of 2 */ +#ifndef _M_LN2 +#define _M_LN2 0.693147180559945309417f +#endif + +/** + * On success, the function return the base 2 logarithm of x. + * maximum error ±0.00493976 + * + * If x is 1, the result is +0. + * If x is 0, the result is -infinity + * If x is negative a NaN (not a number) is returned. + */ +float log2f(float x) { + float2bits m; + + m.number = x; + + if (x == 0) { + m.bits = (int32_t) 0xFF800000; // -inf + return m.number; + } else if (x == 1) { + return (float) 0; + } else if (x < 0) { + m.bits = (int32_t) 0x7F800001; // nan + return m.number; + } + + register float log2 = (float)(((m.bits >> 23) & 0x00FF) - 128); + + m.bits &= ~(255 << 23); + m.bits += (127 << 23); + + log2 += ((-0.34484843f) * m.number + 2.02466578f) * m.number - 0.67487759f; + + return log2; +} + +float logf(float v) { + return log2f(v) * _M_LN2; +} diff --git a/lib-c/src/malloc.c b/lib-clib/src/malloc.c old mode 100644 new mode 100755 similarity index 90% rename from lib-c/src/malloc.c rename to lib-clib/src/malloc.c index e6af3cb..5867677 --- a/lib-c/src/malloc.c +++ b/lib-clib/src/malloc.c @@ -8,7 +8,7 @@ * Copyright (C) 2014-2016 R. Stange * https://github.com/rsta2/circle/blob/master/lib/alloc.cpp */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,15 +32,18 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpointer-arith" // FIXME ignored "-Wpointer-arith" #pragma GCC diagnostic ignored "-Wpedantic" // FIXME ignored "-Wpedantic" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" #include #include #include -#ifdef MEM_DEBUG +#ifdef DEBUG_HEAP #include #endif +extern void console_error(const char *); + extern unsigned char heap_low; /* Defined by the linker */ extern unsigned char heap_top; /* Defined by the linker */ @@ -58,14 +61,20 @@ struct block_header { struct block_bucket { unsigned int size; -#ifdef MEM_DEBUG +#ifdef DEBUG_HEAP unsigned int count; unsigned int max_count; #endif struct block_header *free_list; }; -static struct block_bucket s_block_bucket[] __attribute__((aligned(4))) = {{0x10, 0}, {0x20, 0}, {0x40, 0}, {0x60, 0}, {0x80,0}, {0x100,0}, {0x140,0}, {0x180,0}, {0x200,0}, {0x300,0}, {0x400,0}, {0x500,0}, {0,0}}; +#if defined (H3) +# include "h3/malloc.h" +#elif defined (GD32) +# include "gd32/malloc.h" +#else +# include "rpi/malloc.h" +#endif size_t get_allocated(void *p) { if (p == 0) { @@ -83,9 +92,6 @@ size_t get_allocated(void *p) { } void *malloc(size_t size) { -#ifdef MEM_DEBUG - printf("malloc: %u\n", size); -#endif struct block_bucket *bucket; struct block_header *header; @@ -96,7 +102,7 @@ void *malloc(size_t size) { for (bucket = s_block_bucket; bucket->size > 0; bucket++) { if (size <= bucket->size) { size = bucket->size; -#ifdef MEM_DEBUG +#ifdef DEBUG_HEAP if (++bucket->count > bucket->max_count) { bucket->max_count = bucket->count; } @@ -120,9 +126,7 @@ void *malloc(size_t size) { assert(((unsigned)next & (unsigned)3) == 0); if (next > block_limit) { -#ifdef MEM_DEBUG - printf("malloc: next > block_limit\n"); -#endif + console_error("next > block_limit\n"); return NULL; } else { next_block = next; @@ -133,8 +137,8 @@ void *malloc(size_t size) { } header->next = 0; -#ifdef MEM_DEBUG - printf("malloc: pBlockHeader=%p, size=%d, data=%p\n", header, (int) size, (void *)header->data); +#ifdef DEBUG_HEAP + printf("malloc: pBlockHeader = %p, size = %d\n", header, (int) size); #endif assert(((unsigned)header->data & (unsigned)3) == 0); @@ -150,7 +154,7 @@ void free(void *p) { struct block_header *header = (struct block_header *) ((void *) p - sizeof(struct block_header)); -#ifdef MEM_DEBUG +#ifdef DEBUG_HEAP printf("free: pBlockHeader = %p, pBlock = %p\n", header, p); #endif @@ -164,7 +168,7 @@ void free(void *p) { header->next = bucket->free_list; bucket->free_list = header; -#ifdef MEM_DEBUG +#ifdef DEBUG_HEAP bucket->count--; #endif break; @@ -258,8 +262,8 @@ void *realloc(void *ptr, size_t size) { return newblk; } -void mem_info(void) { -#ifdef MEM_DEBUG +void debug_heap(void) { +#ifdef DEBUG_HEAP struct block_bucket *pBucket; struct block_header *pBlockHeader; printf("s_pNextBlock = %p\n", next_block); diff --git a/lib-clib/src/memchr.c b/lib-clib/src/memchr.c new file mode 100755 index 0000000..ca055d2 --- /dev/null +++ b/lib-clib/src/memchr.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +void* memchr(const void *src, int c, size_t len) { + const unsigned char *s = src; + + while (len--) { + if (*s == (unsigned char) c) + return (void*) s; + s++; + } + + return NULL; +} diff --git a/lib-clib/src/memcmp.c b/lib-clib/src/memcmp.c new file mode 100755 index 0000000..7b1a185 --- /dev/null +++ b/lib-clib/src/memcmp.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +int memcmp(const void *s1, const void *s2, size_t len) +{ + const unsigned char *s = s1; + const unsigned char *d = s2; + unsigned char sc; + unsigned char dc; + + while (len--) { + sc = *s++; + dc = *d++; + if (sc - dc) + return (sc - dc); + } + + return 0; +} diff --git a/lib-c/src/memcpy.c b/lib-clib/src/memcpy.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/memcpy.c rename to lib-clib/src/memcpy.c diff --git a/lib-c/src/memmove.c b/lib-clib/src/memmove.c similarity index 100% rename from lib-c/src/memmove.c rename to lib-clib/src/memmove.c diff --git a/lib-c/src/memset.c b/lib-clib/src/memset.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/memset.c rename to lib-clib/src/memset.c diff --git a/lib-clib/src/perror.c b/lib-clib/src/perror.c new file mode 100755 index 0000000..dd443b8 --- /dev/null +++ b/lib-clib/src/perror.c @@ -0,0 +1,105 @@ +/** + * @file perror.c + * + */ +/* Copyright (C) 2020 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +extern void console_error(const char *); +extern int console_putc(int); +extern int console_puts(const char *); + +/* +errno -l | cut -f3- -d ' ' | sort -V -u | awk '$0="\""$0"\","' +*/ + +const char * const sys_errlist[] = { + "OK", + "Operation not permitted", + "No such file or directory", + "No such process", + "Interrupted system call", + "Input/output error", + "No such device or address", + "Argument list too long", + "Exec format error", + "Bad file descriptor", + "No child processes", + "Resource temporarily unavailable", + "Cannot allocate memory", + "Permission denied", + "Bad address", + "Block device required", + "Device or resource busy", + "File exists", + "Invalid cross-device link", + "No such device", + "Not a directory", + "Is a directory", + "Invalid argument", + "Too many open files in system", + "Too many open files", + "Inappropriate ioctl for device", + "Text file busy", + "File too large", + "No space left on device", + "Illegal seek", + "Read-only file system", + "Too many links", + "Broken pipe", + "Numerical argument out of domain", + "Numerical result out of range", + "Resource deadlock avoided", + "File name too long", + "No locks available", + "Function not implemented", + "Directory not empty", + "Bad message" +}; + +char *strerror(int errnum) { + if (errnum <= ELAST) { + return (char *)sys_errlist[errnum]; + } + + return (char *)sys_errlist[EBADMSG]; +} + +void perror(const char *s) { + const char *ptr = NULL; + + if (errno >= 0 && errno < ELAST) { + ptr = sys_errlist[errno]; + } else { + ptr = sys_errlist[EBADMSG]; + } + + if (s && *s) { + console_error(s); + console_puts(": "); + } + + console_error(ptr); + console_putc('\n'); +} diff --git a/lib-c/src/printf.c b/lib-clib/src/printf.c old mode 100644 new mode 100755 similarity index 92% rename from lib-c/src/printf.c rename to lib-clib/src/printf.c index 24b240b..0ba6756 --- a/lib-c/src/printf.c +++ b/lib-clib/src/printf.c @@ -2,7 +2,7 @@ * @file printf.c * */ -/* Copyright (C) 2016-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2016-2023 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,6 @@ #include #include #include -#include extern int console_putc(int); @@ -53,7 +52,7 @@ enum { static char *outptr = NULL; -inline static void _xputch(struct context *ctx, int c) { +inline static void _xputch(struct context *ctx, const int c) { ctx->total++; if (outptr != NULL) { @@ -78,7 +77,7 @@ static int _pow10(int n) { return r; } -static int _itostr(int x, /*@out@*/char *s, int d) { +static int _itostr(int x, char *s, int d) { char buffer[64]; char *p = buffer + (sizeof(buffer) / sizeof(buffer[0])) - 1; char *o = p; @@ -123,7 +122,7 @@ static int _itostr(int x, /*@out@*/char *s, int d) { return i + 1; } -static void _round_float(/*@out@*/char *dest, int *size) { +static void _round_float(char *dest, int *size) { int i = *size - 1; char *q = (char *) dest + i; bool round_int = false; @@ -175,7 +174,7 @@ static void _round_float(/*@out@*/char *dest, int *size) { #endif static void _format_hex(struct context *ctx, unsigned int arg) { - char buffer[64] __attribute__((aligned(4))); + char buffer[64]; char *p = buffer + (sizeof(buffer) / sizeof(buffer[0])) - 1; char *o = p; char alpha; @@ -227,7 +226,7 @@ static void _format_hex(struct context *ctx, unsigned int arg) { } } -static void _format_int(struct context *ctx, uint64_t arg) { +static void _format_int(struct context *ctx, unsigned long int arg) { char buffer[64]; char *p = buffer + (sizeof(buffer) / sizeof(buffer[0])) - 1; char *o = p; @@ -281,7 +280,7 @@ static void _format_int(struct context *ctx, uint64_t arg) { #if !defined (DISABLE_PRINTF_FLOAT) static void _format_float(struct context *ctx, float f) { - char buffer[64] __attribute__((aligned(4))); + char buffer[64]; char *dest = (char *) buffer; int ipart; int precision; @@ -366,8 +365,8 @@ static int _vprintf(const int size, const char *fmt, va_list va) { #if !defined (DISABLE_PRINTF_FLOAT) float f; #endif - int64_t l; - uint64_t lu; + long int l; + unsigned long int lu; const char *s; ctx.total = 0; @@ -433,12 +432,12 @@ static int _vprintf(const int size, const char *fmt, va_list va) { /*@fallthrough@*/ /* no break */ case 'i': - l = ((ctx.flag & FLAG_LONG) != 0) ? va_arg(va, int64_t) : (int64_t) va_arg(va, int32_t); + l = ((ctx.flag & FLAG_LONG) != 0) ? va_arg(va, long int) : (long int) va_arg(va, int); if (l < 0) { ctx.flag |= FLAG_NEGATIVE; l = -l; } - _format_int(&ctx, (uint64_t) l); + _format_int(&ctx, (unsigned long int) l); break; #if !defined (DISABLE_PRINTF_FLOAT) case 'f': @@ -447,14 +446,14 @@ static int _vprintf(const int size, const char *fmt, va_list va) { break; #endif case 'p': - _format_pointer(&ctx, va_arg(va, uint32_t)); + _format_pointer(&ctx, va_arg(va, unsigned int)); break; case 's': s = va_arg(va, const char *); _format_string(&ctx, s); break; case 'u': - lu = ((ctx.flag & FLAG_LONG) != 0) ? va_arg(va, uint64_t) : va_arg(va,uint32_t); + lu = ((ctx.flag & FLAG_LONG) != 0) ? va_arg(va, unsigned long int) : va_arg(va, unsigned int); _format_int(&ctx, lu); break; case 'X': @@ -462,7 +461,7 @@ static int _vprintf(const int size, const char *fmt, va_list va) { /*@fallthrough@*/ /* no break */ case 'x': - _format_hex(&ctx, va_arg(va, uint32_t)); + _format_hex(&ctx, va_arg(va, unsigned int)); break; default: _xputch(&ctx, (int) *fmt); diff --git a/lib-c/src/putchar.c b/lib-clib/src/putchar.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/putchar.c rename to lib-clib/src/putchar.c diff --git a/lib-c/src/puts.c b/lib-clib/src/puts.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/puts.c rename to lib-clib/src/puts.c diff --git a/lib-c/src/random.c b/lib-clib/src/random.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/random.c rename to lib-clib/src/random.c diff --git a/lib-clib/src/strchr.c b/lib-clib/src/strchr.c new file mode 100755 index 0000000..750a42d --- /dev/null +++ b/lib-clib/src/strchr.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 + +/* + * strchr -- + * + * PUBLIC: #ifndef HAVE_STRCHR + * PUBLIC: char *strchr __P((const char *, int)); + * PUBLIC: #endif + */ +char *strchr(const char *p, int ch) +{ + char c; + + c = (char) ch; + for (;; ++p) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + return (NULL); + } + /* NOTREACHED */ +} diff --git a/lib-network/src/net/tftp_internal.h b/lib-clib/src/strlen.c old mode 100644 new mode 100755 similarity index 82% rename from lib-network/src/net/tftp_internal.h rename to lib-clib/src/strlen.c index 13c9f05..a0eb47f --- a/lib-network/src/net/tftp_internal.h +++ b/lib-clib/src/strlen.c @@ -1,8 +1,8 @@ /** - * @file tftp_internal.h + * @file strlen.c * */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,11 +23,15 @@ * THE SOFTWARE. */ -#ifndef TFTP_INTERNAL_H_ -#define TFTP_INTERNAL_H_ -enum { - TFTP_PORT_SERVER = 69 -}; +#include -#endif /* TFTP_INTERNAL_H_ */ +size_t strlen(const char *s) { + const char *p = s; + + while (*s != (char) 0) { + ++s; + } + + return (size_t) (s - p); +} diff --git a/lib-clib/src/strncmp.c b/lib-clib/src/strncmp.c new file mode 100755 index 0000000..77d962a --- /dev/null +++ b/lib-clib/src/strncmp.c @@ -0,0 +1,51 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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 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 the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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. + */ + +/* + * Portions copyright (c) 2018, Arm Limited and Contributors. + * All rights reserved. + */ + +#include + +int strncmp(const char *s1, const char *s2, size_t n) { + + if (n == 0) + return (0); + do { + if (*s1 != *s2++) + return (*(const unsigned char*) s1 + - *(const unsigned char*) (s2 - 1)); + if (*s1++ == '\0') + break; + } while (--n != 0); + return (0); +} diff --git a/lib-clib/src/strstr.c b/lib-clib/src/strstr.c new file mode 100755 index 0000000..29d74bb --- /dev/null +++ b/lib-clib/src/strstr.c @@ -0,0 +1,71 @@ +/* + * strstr.c -- + * + * Source code for the "strstr" library routine. + * + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: strstr.c,v 1.1.1.3 2003/03/06 00:09:04 landonf Exp $ + */ + +/* + *---------------------------------------------------------------------- + * + * strstr -- + * + * Locate the first instance of a substring in a string. + * + * Results: + * If string contains substring, the return value is the + * location of the first matching instance of substring + * in string. If string doesn't contain substring, the + * return value is 0. Matching is done on an exact + * character-for-character basis with no wildcards or special + * characters. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +#include + +char *strstr(const char *string, const char *substring) { + /* First scan quickly through the two strings looking for a + * single-character match. When it's found, then compare the + * rest of the substring. + */ + + const char *b = substring; + + if (*b == 0) { + return (char *)string; + } + + for (; *string != 0; string += 1) { + if (*string != *b) { + continue; + } + + const char *a = string; + + while (1) { + if (*b == 0) { + return (char *)string; + } + + if (*a++ != *b++) { + break; + } + } + + b = substring; + } + + return NULL; +} diff --git a/lib-c/src/strtok.c b/lib-clib/src/strtok.c old mode 100644 new mode 100755 similarity index 100% rename from lib-c/src/strtok.c rename to lib-clib/src/strtok.c diff --git a/lib-clib/src/strtoul.c b/lib-clib/src/strtoul.c new file mode 100755 index 0000000..2581ed1 --- /dev/null +++ b/lib-clib/src/strtoul.c @@ -0,0 +1,118 @@ +#pragma GCC push_options +#pragma GCC diagnostic ignored "-Wsign-conversion" +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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 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 the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 +#include +#include +#include + +static int isspace(int c) { + return (c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || c == ' ' ? 1 : 0); +} + +/* + * Convert a string to an unsigned long integer. + * + * Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long strtoul(const char *nptr, char **endptr, int base) +{ + const char *s; + unsigned long acc; + char c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace((unsigned char)c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X') && + ((s[1] >= '0' && s[1] <= '9') || + (s[1] >= 'A' && s[1] <= 'F') || + (s[1] >= 'a' && s[1] <= 'f'))) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + acc = any = 0; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/lib-c/src/time.c b/lib-clib/src/time.cpp old mode 100644 new mode 100755 similarity index 54% rename from lib-c/src/time.c rename to lib-clib/src/time.cpp index 0f08b95..86fe621 --- a/lib-c/src/time.c +++ b/lib-clib/src/time.cpp @@ -1,8 +1,8 @@ /** - * @file time.c + * @file time.cpp * */ -/* Copyright (C) 2016-2019 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2016-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,12 +23,19 @@ * THE SOFTWARE. */ -#include +#include + +#include +#include #include -static const int days_of_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +namespace global { +int32_t *gp_nUtcOffset; +} // namespace global + +static constexpr int days_of_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -static int isleapyear(int year) { +static int isleapyear(const int year) { if (year % 100 == 0) { return year % 400 == 0; } @@ -36,7 +43,7 @@ static int isleapyear(int year) { return year % 4 == 0; } -static int getdaysofmonth(int month, int year) { +static int getdaysofmonth(const int month, const int year) { if ((month == 1) && isleapyear(year)) { return 29; } @@ -46,106 +53,120 @@ static int getdaysofmonth(int month, int year) { static struct tm Tm; +extern "C" { + struct tm *localtime(const time_t *pTime) { - int nYear; - int nMonth; + if (pTime == nullptr) { + return nullptr; + } + + auto nTime = *pTime + *global::gp_nUtcOffset; + return gmtime(&nTime); +} - if (pTime == 0) { - return NULL; +struct tm *gmtime(const time_t *pTime) { + if (pTime == nullptr) { + return nullptr; } - time_t Time = *pTime; + auto nTime = *pTime; - Tm.tm_sec = Time % 60; - Time /= 60; - Tm.tm_min = Time % 60; - Time /= 60; - Tm.tm_hour = Time % 24; - Time /= 24; + Tm.tm_sec = nTime % 60; + nTime /= 60; + Tm.tm_min = nTime % 60; + nTime /= 60; + Tm.tm_hour = nTime % 24; + nTime /= 24; - Tm.tm_wday = (Time + 4) % 7; + Tm.tm_wday = (nTime + 4) % 7; + + int nYear = 1970; - nYear = 1970; while (1) { - int nDaysOfYear = isleapyear(nYear) ? 366 : 365; - if (Time < nDaysOfYear) { + const time_t nDaysOfYear = isleapyear(nYear) ? 366 : 365; + if (nTime < nDaysOfYear) { break; } - Time -= nDaysOfYear; + nTime -= nDaysOfYear; nYear++; } Tm.tm_year = nYear - 1900; - Tm.tm_yday = Time; + Tm.tm_yday = nTime; + + int nMonth = 0; - nMonth = 0; while (1) { - int nDaysOfMonth = getdaysofmonth(nMonth, nYear); - if (Time < nDaysOfMonth) { + const time_t nDaysOfMonth = getdaysofmonth(nMonth, nYear); + if (nTime < nDaysOfMonth) { break; } - Time -= nDaysOfMonth; + nTime -= nDaysOfMonth; nMonth++; } Tm.tm_mon = nMonth; - Tm.tm_mday = Time + 1; + Tm.tm_mday = nTime + 1; return &Tm; } time_t mktime(struct tm *pTm) { - int year, month; - time_t result = 0; + time_t nResult = 0; - if (pTm == NULL) { - return (time_t) -1; + if (pTm == nullptr) { + return -1; } if (pTm->tm_year < 70 || pTm->tm_year > 139) { - return (time_t) -1; + return -1; } - for (year = 1970; year < 1900 + pTm->tm_year; year++) { - result += isleapyear(year) ? 366 : 365; + int nYear; + + for (nYear = 1970; nYear < 1900 + pTm->tm_year; nYear++) { + nResult += isleapyear(nYear) ? 366 : 365; } if (pTm->tm_mon < 0 || pTm->tm_mon > 11) { - return (time_t) -1; + return -1; } - for (month = 0; month < pTm->tm_mon; month++) { - result += getdaysofmonth(month, pTm->tm_year); + int nMonth; + + for (nMonth = 0; nMonth < pTm->tm_mon; nMonth++) { + nResult += getdaysofmonth(nMonth, pTm->tm_year); } if (pTm->tm_mday < 1 || pTm->tm_mday > getdaysofmonth(pTm->tm_mon, pTm->tm_year)) { - return (time_t) -1; + return -1; } - result += pTm->tm_mday - 1; - result *= 24; + nResult += pTm->tm_mday - 1; + nResult *= 24; if (pTm->tm_hour < 0 || pTm->tm_hour > 23) { - return (time_t) -1; + return -1; } - result += pTm->tm_hour; - result *= 60; + nResult += pTm->tm_hour; + nResult *= 60; if (pTm->tm_min < 0 || pTm->tm_min > 59) { - return (time_t) -1; + return -1; } - result += pTm->tm_min; - result *= 60; + nResult += pTm->tm_min; + nResult *= 60; if (pTm->tm_sec < 0 || pTm->tm_sec > 59) { - return (time_t) -1; + return -1; } - result += pTm->tm_sec; + nResult += pTm->tm_sec; - return result; + return nResult; +} } diff --git a/lib-configstore/src/storenetwork.cpp b/lib-clib/src/uuid_internal.h similarity index 75% rename from lib-configstore/src/storenetwork.cpp rename to lib-clib/src/uuid_internal.h index 0ed3c4a..1a4530d 100755 --- a/lib-configstore/src/storenetwork.cpp +++ b/lib-clib/src/uuid_internal.h @@ -1,8 +1,8 @@ /** - * @file storenetwork.cpp + * @file uuid_internal.h * */ -/* Copyright (C) 2018-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2016-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,19 +23,17 @@ * THE SOFTWARE. */ -#include +#ifndef UUID_INTERNAL_H_ +#define UUID_INTERNAL_H_ -#include "storenetwork.h" -#include "debug.h" +#include -StoreNetwork *StoreNetwork::s_pThis = nullptr; +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint16_t clock_seq; + uint8_t node[6]; +}; -StoreNetwork::StoreNetwork() { - DEBUG_ENTRY - - assert(s_pThis == nullptr); - s_pThis = this; - - DEBUG_PRINTF("%p", reinterpret_cast(s_pThis)); - DEBUG_EXIT -} +#endif /* UUID_INTERNAL_H_ */ diff --git a/lib-clib/src/uuid_parse.c b/lib-clib/src/uuid_parse.c new file mode 100755 index 0000000..462b96a --- /dev/null +++ b/lib-clib/src/uuid_parse.c @@ -0,0 +1,171 @@ +/** + * @file uuid_parse.c + * + */ +/** + * This code is inspired by: + * http://code.metager.de/source/xref/linux/utils/util-linux/libuuid/src/ + * + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * %Begin-Header% + * 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * %End-Header% + */ +/* Copyright (C) 2016-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "uuid_internal.h" + +static uint32_t hex_uint32(const char *s) { + uint32_t ret = 0; + uint8_t nibble; + + while (*s != '\0') { + char d = *s; + + if (isxdigit((int) d) == 0) { + break; + } + + nibble = d > '9' ? (uint8_t)((uint8_t)( d | 0x20) - 'a' + 10) : (uint8_t) (d - '0'); + ret = (ret << 4) | nibble; + s++; + } + + return ret; +} + +static void uuid_pack(const struct uuid *uu, uuid_t ptr) { + uint32_t tmp; + unsigned char *out = ptr; + + assert(uu != NULL); + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out + 10, uu->node, 6); +} + +int uuid_parse(const char *in, uuid_t uu) { + struct uuid uuid; + int i; + const char *cp; + char buf[3]; + + assert(in != NULL); + + if (strlen(in) != 36) { + return -1; + } + + for (i = 0, cp = in; i <= 36; i++, cp++) { + + if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { + if (*cp == '-') { + continue; + } else { + return -1; + } + } + + if (i == 36) { + if (*cp == 0) { + continue; + } + } + + if (!isxdigit(*cp)) { + return -1; + } + } + + uuid.time_low = hex_uint32(in); + uuid.time_mid = (uint16_t)(hex_uint32(in + 9)); + uuid.time_hi_and_version = (uint16_t)(hex_uint32(in + 14)); + uuid.clock_seq = (uint16_t)(hex_uint32(in + 19)); + + cp = in + 24; + buf[2] = 0; + + for (i = 0; i < 6; i++) { + buf[0] = *cp++; + buf[1] = *cp++; + uuid.node[i] = (uint8_t)(hex_uint32(buf)); + } + + uuid_pack(&uuid, uu); + + return 0; +} diff --git a/lib-clib/src/uuid_unparse.c b/lib-clib/src/uuid_unparse.c new file mode 100755 index 0000000..5c01249 --- /dev/null +++ b/lib-clib/src/uuid_unparse.c @@ -0,0 +1,133 @@ +/** + * @file uuid_unparse.c + * + */ +/** + * This code is inspired by: + * http://code.metager.de/source/xref/linux/utils/util-linux/libuuid/src/ + * + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * %Begin-Header% + * 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, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * %End-Header% + */ +/* Copyright (C) 2016-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "uuid_internal.h" + +#ifndef ALIGNED + #define ALIGNED __attribute__ ((aligned (4))) +#endif + +static const char *fmt_lower ALIGNED = "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"; +static const char *fmt_upper ALIGNED = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"; + +#ifdef UUID_UNPARSE_DEFAULT_UPPER +#define FMT_DEFAULT fmt_upper +#else +#define FMT_DEFAULT fmt_lower +#endif + +static void uuid_unpack(const uuid_t in, struct uuid *uu) { + const uint8_t *ptr = in; + uint32_t tmp; + + assert(uu != NULL); + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = (uint16_t)(tmp); + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = (uint16_t)(tmp); + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = (uint16_t)(tmp); + + memcpy(uu->node, ptr, 6); +} + +static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt) { + struct uuid uuid; + + assert(out != NULL); + assert(fmt != NULL); + + uuid_unpack(uu, &uuid); + + sprintf(out, fmt, uuid.time_low, uuid.time_mid, uuid.time_hi_and_version, + uuid.clock_seq >> 8, uuid.clock_seq & 0xFF, uuid.node[0], + uuid.node[1], uuid.node[2], uuid.node[3], uuid.node[4], + uuid.node[5]); +} + +void uuid_unparse_lower(const uuid_t uu, char *out) { + uuid_unparse_x(uu, out, fmt_lower); +} + +void uuid_unparse_upper(const uuid_t uu, char *out) { + uuid_unparse_x(uu, out, fmt_upper); +} + +void uuid_unparse(const uuid_t uu, char *out) { + uuid_unparse_x(uu, out, FMT_DEFAULT); +} diff --git a/lib-configstore/.cproject b/lib-configstore/.cproject index 3ce2a62..16b4195 100755 --- a/lib-configstore/.cproject +++ b/lib-configstore/.cproject @@ -23,7 +23,6 @@ @@ -89,13 +85,10 @@ - - - diff --git a/lib-configstore/.settings/language.settings.xml b/lib-configstore/.settings/language.settings.xml index 1744551..53c4b5e 100755 --- a/lib-configstore/.settings/language.settings.xml +++ b/lib-configstore/.settings/language.settings.xml @@ -1,15 +1,27 @@ - + - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib-configstore/Makefile.GD32 b/lib-configstore/Makefile.GD32 index 38b1a69..643fe9b 100644 --- a/lib-configstore/Makefile.GD32 +++ b/lib-configstore/Makefile.GD32 @@ -1,8 +1,12 @@ DEFINES =NDEBUG ifneq ($(MAKE_FLAGS),) + ifneq (,$(findstring CONFIG_STORE_USE_RAM,$(MAKE_FLAGS))) + EXTRA_SRCDIR+=device/ram/gd32 + endif else DEFINES+=CONFIG_STORE_USE_RAM + EXTRA_SRCDIR=device/ram/gd32 endif include Rules.mk diff --git a/lib-configstore/Rules.mk b/lib-configstore/Rules.mk old mode 100644 new mode 100755 index 31498ee..af70068 --- a/lib-configstore/Rules.mk +++ b/lib-configstore/Rules.mk @@ -1,7 +1,6 @@ $(info $$MAKE_FLAGS [${MAKE_FLAGS}]) -EXTRA_INCLUDES =../lib-flashcode/include ../lib-flash/include -EXTRA_INCLUDES+=../lib-hal/include ../lib-properties/include ../lib-lightset/include ../lib-network/include +EXTRA_INCLUDES+=../lib-properties/include ifneq ($(MAKE_FLAGS),) ifneq (,$(findstring CONFIG_STORE_USE_FILE,$(MAKE_FLAGS))) @@ -23,153 +22,10 @@ ifneq ($(MAKE_FLAGS),) ifneq (,$(findstring CONFIG_STORE_USE_SPI,$(MAKE_FLAGS))) EXTRA_SRCDIR+=device/spi endif - - RDM= - - ifneq (,$(findstring ESP8266,$(MAKE_FLAGS))) - EXTRA_SRCDIR+=src/network - EXTRA_INCLUDES+=../lib-network/include - # Remote config is not used with ESP8266 - EXTRA_INCLUDES+=../lib-remoteconfig/include - endif - - ifeq (,$(findstring NO_EMAC,$(MAKE_FLAGS))) - EXTRA_SRCDIR+=src/network - EXTRA_INCLUDES+=../lib-network/include - EXTRA_INCLUDES+=../lib-remoteconfig/include - endif - - ifeq ($(findstring DISPLAY_UDF,$(MAKE_FLAGS)), DISPLAY_UDF) - EXTRA_SRCDIR+=src/displayudf - EXTRA_INCLUDES+=../lib-displayudf/include - endif - - ifeq ($(findstring NODE_ARTNET,$(MAKE_FLAGS)), NODE_ARTNET) - EXTRA_SRCDIR+=src/artnet - EXTRA_INCLUDES+=../lib-artnet/include - EXTRA_SRCDIR+=src/rdm - RDM=1 - EXTRA_INCLUDES+=../lib-rdm/include ../lib-rdmsensor/include ../lib-rdmsubdevice/include - ifeq ($(findstring ARTNET_VERSION=4,$(MAKE_FLAGS)), ARTNET_VERSION=4) - EXTRA_INCLUDES+=../lib-e131/include - endif - endif - - ifeq ($(findstring NODE_E131,$(MAKE_FLAGS)), NODE_E131) - EXTRA_SRCDIR+=src/e131 - EXTRA_INCLUDES+=../lib-e131/include - endif - - ifeq ($(findstring NODE_LTC_SMPTE,$(MAKE_FLAGS)), NODE_LTC_SMPTE) - EXTRA_SRCDIR+=src/ltc - EXTRA_INCLUDES+=../lib-ltc/include ../lib-tcnet/include - EXTRA_INCLUDES+=../lib-gps/include - EXTRA_INCLUDES+=../lib-rgbpanel/include - EXTRA_INCLUDES+=../lib-ws28xx/include - endif - - ifeq ($(findstring NODE_NODE,$(MAKE_FLAGS)), NODE_NODE) - EXTRA_SRCDIR+=src/node - EXTRA_INCLUDES+=../lib-node/include - EXTRA_INCLUDES+=../lib-artnet/include ../lib-rdmdiscovery/include - EXTRA_INCLUDES+=../lib-e131/include - endif - - ifeq ($(findstring NODE_OSC_CLIENT,$(MAKE_FLAGS)), NODE_OSC_CLIENT) - EXTRA_SRCDIR+=src/oscclient - EXTRA_INCLUDES+=../lib-oscclient/include - endif - - ifeq ($(findstring OUTPUT_DMX_SEND,$(MAKE_FLAGS)),OUTPUT_DMX_SEND) - EXTRA_SRCDIR+=src/dmx - EXTRA_INCLUDES+=../lib-dmx/include - endif - - ifeq ($(findstring OUTPUT_DMX_PIXEL,$(MAKE_FLAGS)), OUTPUT_DMX_PIXEL) - EXTRA_SRCDIR+=src/pixel - EXTRA_INCLUDES+=../lib-ws28xxdmx/include ../lib-ws28xx/include - endif - - ifeq ($(findstring OUTPUT_DMX_SHOWFILE,$(MAKE_FLAGS)), OUTPUT_DMX_SHOWFILE) - EXTRA_SRCDIR+=src/showfile - EXTRA_INCLUDES+=../lib-showfile/include - endif - - ifeq ($(findstring OUTPUT_DMX_SERIAL,$(MAKE_FLAGS)), OUTPUT_DMX_SERIAL) - EXTRA_SRCDIR+=src/dmxserial - EXTRA_INCLUDES+=../lib-dmxserial/include - endif - - ifeq ($(findstring OUTPUT_DMX_STEPPER,$(MAKE_FLAGS)), OUTPUT_DMX_STEPPER) - EXTRA_SRCDIR+=src/stepper - EXTRA_INCLUDES+=../lib-l6470dmx/include ../lib-l6470/include - endif - - ifeq ($(findstring OUTPUT_DMX_TLC59711,$(MAKE_FLAGS)), OUTPUT_DMX_TLC59711) - EXTRA_SRCDIR+=src/tlc59711 - EXTRA_INCLUDES+=../lib-tlc59711dmx/include ../lib-tlc59711/include - endif - - ifeq ($(findstring RDM_CONTROLLER,$(MAKE_FLAGS)), RDM_CONTROLLER) - ifdef RDM - else - EXTRA_SRCDIR+=src/rdm - RDM=1 - endif - endif - - ifeq ($(findstring RDM_RESPONDER,$(MAKE_FLAGS)), RDM_RESPONDER) - ifdef RDM - else - EXTRA_SRCDIR+=src/rdm - RDM=1 - endif - EXTRA_INCLUDES+=../lib-rdmresponder/include - endif - - ifeq ($(findstring NODE_RDMNET_LLRP_ONLY,$(MAKE_FLAGS)), NODE_RDMNET_LLRP_ONLY) - ifdef RDM - else - EXTRA_SRCDIR+=src/rdm - RDM=1 - endif - EXTRA_INCLUDES+=../lib-rdm/include ../lib-rdmsensor/include ../lib-rdmsubdevice/include - endif - - ifeq ($(findstring WIDGET_HAVE_FLASHROM,$(MAKE_FLAGS)), WIDGET_HAVE_FLASHROM) - EXTRA_SRCDIR+=src/widget - EXTRA_INCLUDES+=../lib-widget/include - endif else - EXTRA_SRCDIR+=src/artnet - EXTRA_INCLUDES+=../lib-artnet/include - EXTRA_SRCDIR+=src/e131 - EXTRA_INCLUDES+=../lib-e131/include - EXTRA_SRCDIR+=src/node - EXTRA_INCLUDES+=../lib-node/include ../lib-rdmdiscovery/include - EXTRA_SRCDIR+=src/ltc - EXTRA_INCLUDES+=../lib-ltc/include ../lib-tcnet/include - EXTRA_INCLUDES+=../lib-gps/include - EXTRA_INCLUDES+=../lib-rgbpanel/include - EXTRA_INCLUDES+=../lib-ws28xx/include - EXTRA_SRCDIR+=src/rdm - EXTRA_INCLUDES+=../lib-rdm/include ../lib-rdmsensor/include ../lib-rdmsubdevice/include - EXTRA_SRCDIR+=src/stepper - EXTRA_INCLUDES+=../lib-l6470dmx/include ../lib-l6470/include - EXTRA_INCLUDES+=../lib-tlc59711dmx/include ../lib-tlc59711/include - - DEFINES+=ARTNET_VERSION=4 - DEFINES+=LIGHTSET_PORTS=4 - DEFINES+=CONFIG_PIXELDMX_MAX_PORTS=8 - DEFINES+=CONFIG_DDPDISPLAY_MAX_PORTS=8 + EXTRA_SRCDIR+=device/file + EXTRA_SRCDIR+=device/i2c + EXTRA_SRCDIR+=device/ram + EXTRA_SRCDIR+=device/rom + EXTRA_SRCDIR+=device/spi endif - -EXTRA_INCLUDES+=../lib-displayudf/include ../lib-display/include -EXTRA_INCLUDES+=../lib-dmxsend/include -EXTRA_INCLUDES+=../lib-dmxmonitor/include -EXTRA_INCLUDES+=../lib-dmxreceiver/include ../lib-dmx/include -EXTRA_INCLUDES+=../lib-oscserver/include -EXTRA_INCLUDES+=../lib-rdm/include ../lib-rdmsensor/include ../lib-rdmsubdevice/include -EXTRA_INCLUDES+=../lib-spiflashinstall/include -EXTRA_INCLUDES+=../lib-device/include -EXTRA_INCLUDES+=../lib-midi/include \ No newline at end of file diff --git a/lib-configstore/device/i2c/storedevice.cpp b/lib-configstore/device/i2c/storedevice.cpp old mode 100644 new mode 100755 index 1a4d010..dd6e0e6 --- a/lib-configstore/device/i2c/storedevice.cpp +++ b/lib-configstore/device/i2c/storedevice.cpp @@ -27,8 +27,9 @@ #include #include -#include "storedevice.h" +#include "configstoredevice.h" #include "i2c/at24cxx.h" + #include "debug.h" namespace storedevice { @@ -49,7 +50,7 @@ StoreDevice::StoreDevice() : AT24C32(storedevice::I2C_INDEX) { if (!m_IsDetected) { printf("StoreDevice: No AT24C32 at %2x", AT24C32::GetAddress()); } else { - printf("StoreDevice: Detected AT24C32 with total %u bytes [%u kB]\n", GetSize(), GetSize() / 1024U); + printf("StoreDevice: AT24C32 total %u bytes [%u kB]\n", GetSize(), GetSize() / 1024U); } DEBUG_EXIT @@ -81,7 +82,7 @@ bool StoreDevice::Read(uint32_t nOffset, uint32_t nLength, uint8_t *pBuffer, sto return true; } -bool StoreDevice::Erase(__attribute__((unused)) uint32_t nOffset, __attribute__((unused)) uint32_t nLength, storedevice::result& nResult) { +bool StoreDevice::Erase([[maybe_unused]] uint32_t nOffset, [[maybe_unused]] uint32_t nLength, storedevice::result& nResult) { DEBUG_ENTRY nResult = storedevice::result::OK; diff --git a/lib-configstore/device/ram/gd32/storedevice.cpp b/lib-configstore/device/ram/gd32/storedevice.cpp index 1ad9f6e..ff26c72 100644 --- a/lib-configstore/device/ram/gd32/storedevice.cpp +++ b/lib-configstore/device/ram/gd32/storedevice.cpp @@ -2,7 +2,7 @@ * @file storedevice.cpp * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,8 +27,7 @@ #include #include -#include "storedevice.h" - +#include "configstoredevice.h" #include "gd32.h" #include "debug.h" diff --git a/lib-configstore/device/rom/storedevice.cpp b/lib-configstore/device/rom/storedevice.cpp old mode 100644 new mode 100755 index d9be65d..f06bad4 --- a/lib-configstore/device/rom/storedevice.cpp +++ b/lib-configstore/device/rom/storedevice.cpp @@ -26,8 +26,7 @@ #include #include -#include "storedevice.h" - +#include "configstoredevice.h" #include "flashcode.h" #include "debug.h" diff --git a/lib-configstore/device/spi/storedevice.cpp b/lib-configstore/device/spi/storedevice.cpp old mode 100644 new mode 100755 index 4f3cb7f..1c77549 --- a/lib-configstore/device/spi/storedevice.cpp +++ b/lib-configstore/device/spi/storedevice.cpp @@ -2,7 +2,7 @@ * @file storedevice.cpp * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +26,9 @@ #include #include -#include "storedevice.h" +#include "configstoredevice.h" #include "spi/spi_flash.h" + #include "debug.h" StoreDevice::StoreDevice() { @@ -36,11 +37,11 @@ StoreDevice::StoreDevice() { if (spi_flash_probe(0, 0, 0) < 0) { DEBUG_PUTS("No SPI flash chip"); } else { - printf("StoreDevice: Detected %s with sector size %u total %u bytes [%u kB]\n", + printf("StoreDevice: %s sector size %u total %u bytes [%u kB]\n", spi_flash_get_name(), - spi_flash_get_sector_size(), - spi_flash_get_size(), - spi_flash_get_size() / 1024U); + static_cast(spi_flash_get_sector_size()), + static_cast(spi_flash_get_size()), + static_cast(spi_flash_get_size() / 1024U)); m_IsDetected = true; } diff --git a/lib-configstore/include/configstore.h b/lib-configstore/include/configstore.h old mode 100755 new mode 100644 index 73b23ae..bb69861 --- a/lib-configstore/include/configstore.h +++ b/lib-configstore/include/configstore.h @@ -2,7 +2,7 @@ * @file configstore.h * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,8 +27,14 @@ #define CONFIGSTORE_H_ #include +#include +#include -#include "storedevice.h" +#include "configstoredevice.h" + +#include "utc.h" + +#include "debug.h" namespace configstore { enum class Store { @@ -58,13 +64,13 @@ enum class Store { GPS, RGBPANEL, NODE, + PCA9685, LAST }; enum class State { IDLE, CHANGED, CHANGED_WAITING, ERASING, ERASED, ERASED_WAITING, WRITING }; - } // namespace configstore class ConfigStore: StoreDevice { @@ -75,18 +81,19 @@ class ConfigStore: StoreDevice { ; } - bool HaveFlashChip() const { - return s_bHaveFlashChip; - } - void Update(configstore::Store store, uint32_t nOffset, const void *pData, uint32_t nDataLength, uint32_t nSetList = 0, uint32_t nOffsetSetList = 0); void Update(configstore::Store store, const void *pData, uint32_t nDataLength) { Update(store, 0, pData, nDataLength); } - void Copy(const configstore::Store store, void *pData, uint32_t nDataLength, uint32_t nOffset = 0); + void Copy(const configstore::Store store, void *pData, uint32_t nDataLength, uint32_t nOffset = 0, const bool doUpdate = true); void ResetSetList(configstore::Store store); + void ResetSetListAll() { + for (uint32_t i = 0; i < static_cast(configstore::Store::LAST); i++) { + ResetSetList(static_cast(i)); + } + } bool Flash(); @@ -94,6 +101,53 @@ class ConfigStore: StoreDevice { void Delay(); + /* + * Environment + */ + + bool SetEnvUtcOffset(const int8_t nHours, const uint8_t nMinutes) { + int32_t nUtcOffset; + + DEBUG_PRINTF("nHours=%d, nMinutes =%u", nHours, nMinutes); + + if (hal::utc_validate(nHours, nMinutes, nUtcOffset)) { + auto *p = reinterpret_cast(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE]); + + if (p->nUtcOffset != nUtcOffset) { + p->nUtcOffset = nUtcOffset; + s_State = configstore::State::CHANGED; + } + + DEBUG_EXIT + return true; + } + + DEBUG_EXIT + return false; + } + + void GetEnvUtcOffset(int8_t& nHours, uint8_t& nMinutes) { + const auto *p = reinterpret_cast(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE]); + + DEBUG_PRINTF("p->nUtcOffset=%d", p->nUtcOffset); + + assert((p->nUtcOffset / 3600) <= INT8_MAX); + assert((p->nUtcOffset / 3600) >= INT8_MIN); + + nHours = static_cast(p->nUtcOffset / 3600); + + if (nHours > 0) { + nMinutes = static_cast(static_cast(p->nUtcOffset - (nHours * 3600)) / 60U); + } else { + nMinutes = static_cast(static_cast((nHours * 3600) - p->nUtcOffset) / 60U); + } + } + + int32_t GetEnvUtcOffset() const { + const auto *p = reinterpret_cast(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE]); + return p->nUtcOffset; + } + static ConfigStore *Get() { return s_pThis; } @@ -102,10 +156,20 @@ class ConfigStore: StoreDevice { uint32_t GetStoreOffset(configstore::Store tStore); private: + struct Env { + int32_t nUtcOffset; + uint8_t filler[12]; + }; + struct FlashStore { - static constexpr auto SIZE = 4096U; + static constexpr uint32_t SIGNATURE_SIZE = 16; + static constexpr uint32_t ENV_SIZE = 16; + static constexpr uint32_t OFFSET_STORES = SIGNATURE_SIZE + ENV_SIZE; + static constexpr uint32_t SIZE = 4096; }; + static_assert(sizeof(struct Env) == FlashStore::ENV_SIZE, ""); + static bool s_bHaveFlashChip; static configstore::State s_State; diff --git a/lib-configstore/include/storedevice.h b/lib-configstore/include/configstoredevice.h similarity index 100% rename from lib-configstore/include/storedevice.h rename to lib-configstore/include/configstoredevice.h diff --git a/lib-configstore/include/envparams.h b/lib-configstore/include/envparams.h new file mode 100755 index 0000000..6333389 --- /dev/null +++ b/lib-configstore/include/envparams.h @@ -0,0 +1,48 @@ +/** + * @file envparams.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef ENVPARAMS_H_ +#define ENVPARAMS_H_ + +#include + +class EnvParams { +public: + EnvParams(); + + void LoadAndSet(); + void LoadAndSet(const char *pBuffer, uint32_t nLength); + + void Builder(char *pBuffer, uint32_t nLength, uint32_t& nSize); + +public: + static void staticCallbackFunction(void *p, const char *s); + +private: + void Dump(); + void callbackFunction(const char *s); +}; + +#endif /* ENVPARAMS_H_ */ diff --git a/lib-display/src/display_timeout.cpp b/lib-configstore/include/envparamsconst.h old mode 100644 new mode 100755 similarity index 79% rename from lib-display/src/display_timeout.cpp rename to lib-configstore/include/envparamsconst.h index 5b403dd..dcc2ea2 --- a/lib-display/src/display_timeout.cpp +++ b/lib-configstore/include/envparamsconst.h @@ -1,8 +1,8 @@ /** - * @file display_timeout.cpp + * @file envparamsconst.h * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,9 +23,13 @@ * THE SOFTWARE. */ -namespace display { -namespace timeout { -void __attribute__((weak)) gpio_init() {} -bool __attribute__((weak)) gpio_renew() { return false;} -} // namespace timeout -} // namespace display +#ifndef ENVPARAMSCONST_H_ +#define ENVPARAMSCONST_H_ + +struct EnvParamsConst { + static const char FILE_NAME[]; + + static const char UTC_OFFSET[]; +}; + +#endif /* ENVPARAMSCONST_H_ */ diff --git a/lib-configstore/include/storenetwork.h b/lib-configstore/include/storenetwork.h deleted file mode 100755 index 427c05b..0000000 --- a/lib-configstore/include/storenetwork.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file storenetwork.h - * - */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STORENETWORK_H_ -#define STORENETWORK_H_ - -#include - -#include "network.h" -#include "networkparams.h" -#include "configstore.h" - -class StoreNetwork final: public NetworkParamsStore, public NetworkStore { -public: - StoreNetwork(); - - void Update(const struct networkparams::Params *pNetworkParams) override { - ConfigStore::Get()->Update(configstore::Store::NETWORK, pNetworkParams, sizeof(struct networkparams::Params)); - } - - void Copy(struct networkparams::Params *pNetworkParams) override { - ConfigStore::Get()->Copy(configstore::Store::NETWORK, pNetworkParams, sizeof(struct networkparams::Params)); - } - - void SaveIp(uint32_t nIp) override { - ConfigStore::Get()->Update(configstore::Store::NETWORK, __builtin_offsetof(struct networkparams::Params, nLocalIp), &nIp, sizeof(uint32_t), networkparams::Mask::IP_ADDRESS); - } - - void SaveNetMask(uint32_t nNetMask) override { - ConfigStore::Get()->Update(configstore::Store::NETWORK, __builtin_offsetof(struct networkparams::Params, nNetmask), &nNetMask, sizeof(uint32_t), networkparams::Mask::NET_MASK); - } - - void SaveGatewayIp(uint32_t nGatewayIp) override { - ConfigStore::Get()->Update(configstore::Store::NETWORK, __builtin_offsetof(struct networkparams::Params, nGatewayIp), &nGatewayIp, sizeof(uint32_t), networkparams::Mask::DEFAULT_GATEWAY); - } - - void SaveHostName(const char *pHostName, uint32_t nLength) override { - nLength = std::min(nLength,static_cast(network::HOSTNAME_SIZE)); - ConfigStore::Get()->Update(configstore::Store::NETWORK, __builtin_offsetof(struct networkparams::Params, aHostName), pHostName, nLength, networkparams::Mask::HOSTNAME); - } - - void SaveDhcp(bool bIsDhcpUsed) override { - ConfigStore::Get()->Update(configstore::Store::NETWORK, __builtin_offsetof(struct networkparams::Params, bIsDhcpUsed), &bIsDhcpUsed, sizeof(bool), networkparams::Mask::DHCP); - } - - static StoreNetwork *Get() { - return s_pThis; - } - -private: - static StoreNetwork *s_pThis; -}; - -#endif /* STORENETWORK_H_ */ diff --git a/lib-configstore/include/storeremoteconfig.h b/lib-configstore/include/storeremoteconfig.h deleted file mode 100755 index 46360d4..0000000 --- a/lib-configstore/include/storeremoteconfig.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file storeremoteconfig.h - * - */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STOREREMOTECONFIG_H_ -#define STOREREMOTECONFIG_H_ - -#include "remoteconfigparams.h" - -#include "configstore.h" - -class StoreRemoteConfig final: public RemoteConfigParamsStore { -public: - StoreRemoteConfig(); - - void Update(const struct TRemoteConfigParams *pRemoteConfigParams) override { - ConfigStore::Get()->Update(configstore::Store::RCONFIG, pRemoteConfigParams, sizeof(struct TRemoteConfigParams)); - } - - void Copy(struct TRemoteConfigParams *pRemoteConfigParams) override { - ConfigStore::Get()->Copy(configstore::Store::RCONFIG, pRemoteConfigParams, sizeof(struct TRemoteConfigParams)); - } - - static StoreRemoteConfig *Get() { - return s_pThis; - } - -private: - static StoreRemoteConfig *s_pThis; -}; - -#endif /* STOREREMOTECONFIG_H_ */ diff --git a/lib-configstore/include/storetcnet.h b/lib-configstore/include/storetcnet.h deleted file mode 100755 index 093f77f..0000000 --- a/lib-configstore/include/storetcnet.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file storetcnet.h - * - */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STORETCNET_H_ -#define STORETCNET_H_ - -#include "tcnetparams.h" - -#include "spiflashstore.h" - -class StoreTCNet final: public TCNetParamsStore { -public: - StoreTCNet(); - - void Update(const struct tcnetparams::Params *pTCNetParams) override { - SpiFlashStore::Get()->Update(spiflashstore::Store::TCNET, pTCNetParams, sizeof(struct tcnetparams::Params)); - } - - void Copy(struct tcnetparams::Params *pTCNetParams) override { - SpiFlashStore::Get()->Copy(spiflashstore::Store::TCNET, pTCNetParams, sizeof(struct tcnetparams::Params)); - } - - static StoreTCNet *Get() { - return s_pThis; - } - -private: - static StoreTCNet *s_pThis; -}; - -#endif /* STORETCNET_H_ */ diff --git a/lib-configstore/include/storewidget.h b/lib-configstore/include/storewidget.h deleted file mode 100755 index d27820f..0000000 --- a/lib-configstore/include/storewidget.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file storewidget.h - * - */ -/* Copyright (C) 2019-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef STOREWIDGET_H_ -#define STOREWIDGET_H_ - -#include "widgetparams.h" -#include "widgetstore.h" - -#include "spiflashstore.h" - -class StoreWidget final: public WidgetParamsStore, public WidgetStore { -public: - StoreWidget(); - - void Update(const struct TWidgetParams* pWidgetParams) { - SpiFlashStore::Get()->Update(spiflashstore::Store::WIDGET, pWidgetParams, sizeof(struct TWidgetParams)); - } - - void Copy(struct TWidgetParams* pWidgetParams) { - SpiFlashStore::Get()->Copy(spiflashstore::Store::WIDGET, pWidgetParams, sizeof(struct TWidgetParams)); - } - - void UpdateBreakTime(uint8_t nBreakTime) { - SpiFlashStore::Get()->Update(spiflashstore::Store::WIDGET, __builtin_offsetof(struct TWidgetParams, nBreakTime), &nBreakTime, sizeof(uint8_t), WidgetParamsMask::BREAK_TIME); - } - - void UpdateMabTime(uint8_t nMabTime) { - SpiFlashStore::Get()->Update(spiflashstore::Store::WIDGET, __builtin_offsetof(struct TWidgetParams, nMabTime), &nMabTime, sizeof(uint8_t), WidgetParamsMask::MAB_TIME); - } - - void UpdateRefreshRate(uint8_t nRefreshRate) { - SpiFlashStore::Get()->Update(spiflashstore::Store::WIDGET, __builtin_offsetof(struct TWidgetParams, nRefreshRate), &nRefreshRate, sizeof(uint8_t), WidgetParamsMask::REFRESH_RATE); - } - - static StoreWidget* Get() { - return s_pThis; - } - -private: - static StoreWidget *s_pThis; -}; - -#endif /* STOREWIDGET_H_ */ diff --git a/lib-configstore/src/configstore.cpp b/lib-configstore/src/configstore.cpp old mode 100644 new mode 100755 index 5e325d4..4b6bbf2 --- a/lib-configstore/src/configstore.cpp +++ b/lib-configstore/src/configstore.cpp @@ -2,7 +2,7 @@ * @file configstore.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,13 +36,16 @@ #include "debug.h" +namespace global { +extern int32_t *gp_nUtcOffset; +} // namespace global + using namespace configstore; static constexpr uint8_t s_aSignature[] = {'A', 'v', 'V', 0x01}; -static constexpr auto OFFSET_STORES = ((((sizeof(s_aSignature) + 15) / 16) * 16) + 16); // +16 is reserved for future use -static constexpr uint32_t s_aStorSize[static_cast(Store::LAST)] = {96, 32, 64, 64, 32, 32, 480, 64, 32, 96, 48, 32, 944, 48, 64, 32, 96, 32, 1024, 32, 32, 64, 96, 32, 32, 320}; +static constexpr uint32_t s_aStorSize[static_cast(Store::LAST)] = {96, 32, 64, 64, 32, 32, 480, 64, 32, 96, 48, 32, 944, 48, 64, 32, 96, 32, 1024, 32, 32, 64, 96, 32, 32, 320, 32}; #ifndef NDEBUG -static constexpr char s_aStoreName[static_cast(Store::LAST)][16] = {"Network", "DMX", "Pixel", "LTC", "MIDI", "LTC ETC", "OSC Server", "TLC59711", "USB Pro", "RDM Device", "RConfig", "TCNet", "OSC Client", "Display", "LTC Display", "Monitor", "SparkFun", "Slush", "Motors", "Show", "Serial", "RDM Sensors", "RDM SubDevices", "GPS", "RGB Panel", "Node"}; +static constexpr char s_aStoreName[static_cast(Store::LAST)][16] = {"Network", "DMX", "Pixel", "LTC", "MIDI", "LTC ETC", "OSC Server", "TLC59711", "USB Pro", "RDM Device", "RConfig", "TCNet", "OSC Client", "Display", "LTC Display", "Monitor", "SparkFun", "Slush", "Motors", "Show", "Serial", "RDM Sensors", "RDM SubDevices", "GPS", "RGB Panel", "Node", "PCA9685"}; #endif bool ConfigStore::s_bHaveFlashChip; @@ -57,9 +60,13 @@ ConfigStore *ConfigStore::s_pThis; ConfigStore::ConfigStore() { DEBUG_ENTRY + static_assert(sizeof(s_aSignature) <= FlashStore::SIGNATURE_SIZE); + assert(s_pThis == nullptr); s_pThis = this; + global::gp_nUtcOffset = reinterpret_cast(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE]); + s_bHaveFlashChip = StoreDevice::IsDetected(); assert(FlashStore::SIZE <= StoreDevice::GetSize()); @@ -94,20 +101,32 @@ ConfigStore::ConfigStore() { if (!bSignatureOK) { DEBUG_PUTS("No signature"); - memset(&s_SpiFlashData[OFFSET_STORES], 0, FlashStore::SIZE - OFFSET_STORES); + memset(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE], 0, FlashStore::SIZE - FlashStore::SIGNATURE_SIZE); s_State = State::CHANGED; } - s_nSpiFlashStoreSize = OFFSET_STORES; + s_nSpiFlashStoreSize = FlashStore::OFFSET_STORES; for (uint32_t j = 0; j < static_cast(Store::LAST); j++) { s_nSpiFlashStoreSize += s_aStorSize[j]; } - DEBUG_PRINTF("OFFSET_STORES=%d, m_nSpiFlashStoreSize=%d", static_cast(OFFSET_STORES), s_nSpiFlashStoreSize); + DEBUG_PRINTF("FlashStore::OFFSET_STORES=%d, m_nSpiFlashStoreSize=%d", static_cast(FlashStore::OFFSET_STORES), s_nSpiFlashStoreSize); assert(s_nSpiFlashStoreSize <= FlashStore::SIZE); + for (uint32_t nStore = 0; nStore < static_cast(Store::LAST); nStore++) { + auto *pSet = reinterpret_cast((&s_SpiFlashData[GetStoreOffset(static_cast(nStore))])); + if (*pSet == UINT32_MAX) { + *pSet = 0; + } + } + + auto *p = reinterpret_cast(&s_SpiFlashData[FlashStore::SIGNATURE_SIZE]); + if (p->nUtcOffset == -1) { + p->nUtcOffset = 0; + } + DEBUG_PUTS(""); debug_dump(s_SpiFlashData, FlashStore::SIZE); @@ -117,7 +136,7 @@ ConfigStore::ConfigStore() { uint32_t ConfigStore::GetStoreOffset(Store store) { assert(store < Store::LAST); - uint32_t nOffset = OFFSET_STORES; + uint32_t nOffset = FlashStore::OFFSET_STORES; for (uint32_t i = 0; i < static_cast(store); i++) { nOffset += s_aStorSize[i]; @@ -171,9 +190,8 @@ void ConfigStore::Update(Store store, uint32_t nOffset, const void *pData, uint3 pSrc++; } - if ((0 != nOffset) && (bIsChanged) && (nSetList != 0)) { - auto *pSet = reinterpret_cast((&s_SpiFlashData[GetStoreOffset(store)] + nOffsetSetList)); - + if (bIsChanged){ + auto *pSet = reinterpret_cast((&s_SpiFlashData[GetStoreOffset(store)] + nOffsetSetList)); *pSet |= nSetList; } @@ -181,12 +199,13 @@ void ConfigStore::Update(Store store, uint32_t nOffset, const void *pData, uint3 s_State = State::CHANGED; } + debug_dump(&s_SpiFlashData[GetStoreOffset(store)] + nOffsetSetList, 8); DEBUG_EXIT } -void ConfigStore::Copy(const Store store, void *pData, uint32_t nDataLength, uint32_t nOffset) { +void ConfigStore::Copy(const Store store, void *pData, uint32_t nDataLength, uint32_t nOffset, const bool doUpdate) { DEBUG_ENTRY - DEBUG_PRINTF("[%s]:%u pData=%p, nDataLength=%u, nOffset=%u", s_aStoreName[static_cast(store)], static_cast(store), pData, nDataLength, nOffset); + DEBUG_PRINTF("[%s]:%u pData=%p, nDataLength=%u, nOffset=%u, doUpdate=%u", s_aStoreName[static_cast(store)], static_cast(store), pData, nDataLength, nOffset, doUpdate); assert(store < Store::LAST); assert(pData != nullptr); @@ -210,7 +229,9 @@ void ConfigStore::Copy(const Store store, void *pData, uint32_t nDataLength, uin return; } - Update(store, pData, nDataLength); + if (doUpdate) { + Update(store, pData, nDataLength); + } DEBUG_EXIT } @@ -293,8 +314,8 @@ void ConfigStore::Dump() { Hardware::Get()->WatchdogStop(); } - debug_dump(s_SpiFlashData, OFFSET_STORES); - printf("\n"); + debug_dump(s_SpiFlashData, FlashStore::OFFSET_STORES); + puts(""); for (uint32_t j = 0; j < static_cast(Store::LAST); j++) { printf("Store [%s]:%d\n", s_aStoreName[j], j); @@ -302,7 +323,7 @@ void ConfigStore::Dump() { auto *p = &s_SpiFlashData[GetStoreOffset(static_cast(j))]; debug_dump(p, static_cast(s_aStorSize[j])); - printf("\n"); + puts(""); } if (IsWatchDog) { diff --git a/lib-configstore/src/envparams.cpp b/lib-configstore/src/envparams.cpp new file mode 100755 index 0000000..cead222 --- /dev/null +++ b/lib-configstore/src/envparams.cpp @@ -0,0 +1,132 @@ +/** + * @file envparams.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined(__clang__) // Needed for compiling on MacOS +# pragma GCC push_options +# pragma GCC optimize ("Os") +#endif + +#include +#include +#include + +#include "envparams.h" +#include "envparamsconst.h" + +#include "readconfigfile.h" +#include "sscan.h" + +#include "propertiesbuilder.h" + +#include "configstore.h" + +#include "debug.h" + +EnvParams::EnvParams() { + DEBUG_ENTRY + + DEBUG_EXIT +} + +void EnvParams::LoadAndSet() { + DEBUG_ENTRY + + assert(ConfigStore::Get() != nullptr); + +#if !defined(DISABLE_FS) + ReadConfigFile configfile(EnvParams::staticCallbackFunction, this); + configfile.Read(EnvParamsConst::FILE_NAME); +#endif + +#ifndef NDEBUG + Dump(); +#endif + + DEBUG_EXIT +} + +void EnvParams::LoadAndSet(const char *pBuffer, uint32_t nLength) { + DEBUG_ENTRY + + assert(ConfigStore::Get() != nullptr); + + assert(pBuffer != nullptr); + assert(nLength != 0); + + ReadConfigFile config(EnvParams::staticCallbackFunction, this); + config.Read(pBuffer, nLength); + +#ifndef NDEBUG + Dump(); +#endif + DEBUG_EXIT +} + +void EnvParams::callbackFunction(const char *pLine) { + assert(pLine != nullptr); + + int8_t nHours; + uint8_t nMinutes; + + if (Sscan::UtcOffset(pLine, EnvParamsConst::UTC_OFFSET, nHours, nMinutes) == Sscan::OK) { + ConfigStore::Get()->SetEnvUtcOffset(nHours, nMinutes); + return; + } +} + +void EnvParams::staticCallbackFunction(void *p, const char *s) { + assert(p != nullptr); + assert(s != nullptr); + + (static_cast(p))->callbackFunction(s); +} + +void EnvParams::Builder(char *pBuffer, uint32_t nLength, uint32_t& nSize) { + DEBUG_ENTRY + + assert(pBuffer != nullptr); + + PropertiesBuilder builder(EnvParamsConst::FILE_NAME, pBuffer, nLength); + + int8_t nHours; + uint8_t nMinutes; + ConfigStore::Get()->GetEnvUtcOffset(nHours, nMinutes); + builder.AddUtcOffset(EnvParamsConst::UTC_OFFSET, nHours, nMinutes); + + nSize = builder.GetSize(); + + DEBUG_PRINTF("nSize=%d", nSize); + DEBUG_EXIT +} + +void EnvParams::Dump() { + printf("%s::%s \'%s\':\n", __FILE__, __FUNCTION__, EnvParamsConst::FILE_NAME); + + puts("UTC Offset"); + int8_t nHours; + uint8_t nMinutes; + ConfigStore::Get()->GetEnvUtcOffset(nHours, nMinutes); + printf(" %s=%.2d:%.2u [%d]\n", EnvParamsConst::UTC_OFFSET, nHours, nMinutes, ConfigStore::Get()->GetEnvUtcOffset()); +} diff --git a/lib-configstore/src/envparamsconst.cpp b/lib-configstore/src/envparamsconst.cpp new file mode 100755 index 0000000..3788070 --- /dev/null +++ b/lib-configstore/src/envparamsconst.cpp @@ -0,0 +1,30 @@ +/** + * @file envparamsconst.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "envparamsconst.h" + +const char EnvParamsConst::FILE_NAME[] = "env.txt"; + +const char EnvParamsConst::UTC_OFFSET[] = "utc_offset"; diff --git a/lib-configstore/src/platform_configstore.h b/lib-configstore/src/platform_configstore.h old mode 100644 new mode 100755 diff --git a/lib-debug/.cproject b/lib-debug/.cproject deleted file mode 100755 index 23106c1..0000000 --- a/lib-debug/.cproject +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-debug/.project b/lib-debug/.project deleted file mode 100755 index e661d6a..0000000 --- a/lib-debug/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - lib-debug - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/lib-debug/.settings/language.settings.xml b/lib-debug/.settings/language.settings.xml deleted file mode 100755 index 38076f8..0000000 --- a/lib-debug/.settings/language.settings.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib-debug/.settings/org.eclipse.cdt.core.prefs b/lib-debug/.settings/org.eclipse.cdt.core.prefs deleted file mode 100644 index c8ec5df..0000000 --- a/lib-debug/.settings/org.eclipse.cdt.core.prefs +++ /dev/null @@ -1,6 +0,0 @@ -doxygen/doxygen_new_line_after_brief=true -doxygen/doxygen_use_brief_tag=false -doxygen/doxygen_use_javadoc_tags=true -doxygen/doxygen_use_pre_tag=false -doxygen/doxygen_use_structural_commands=false -eclipse.preferences.version=1 diff --git a/lib-debug/.settings/org.eclipse.core.resources.prefs b/lib-debug/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c0..0000000 --- a/lib-debug/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/lib-debug/Makefile.GD32 b/lib-debug/Makefile.GD32 deleted file mode 100644 index e62a508..0000000 --- a/lib-debug/Makefile.GD32 +++ /dev/null @@ -1,3 +0,0 @@ -EXTRA_SRCDIR= - -include ../firmware-template-gd32/lib/Rules.mk \ No newline at end of file diff --git a/lib-display/.cproject b/lib-display/.cproject index 680f965..8a2df3b 100755 --- a/lib-display/.cproject +++ b/lib-display/.cproject @@ -24,7 +24,6 @@ diff --git a/lib-flash/include/spi/spi_flash.h b/lib-flash/include/spi/spi_flash.h index 50df49c..729a61f 100644 --- a/lib-flash/include/spi/spi_flash.h +++ b/lib-flash/include/spi/spi_flash.h @@ -2,7 +2,7 @@ * @file spi_flash.h * */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-flash/src/spi/gd32/spi_flash.cpp b/lib-flash/src/spi/gd32/spi_flash.cpp index 7b2597e..a719e28 100644 --- a/lib-flash/src/spi/gd32/spi_flash.cpp +++ b/lib-flash/src/spi/gd32/spi_flash.cpp @@ -2,7 +2,7 @@ * @file spi_flash.cpp * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,7 @@ #include "./../../spi/spi_flash_internal.h" #include "gd32_spi.h" +#include "gd32_gpio.h" #include "gd32.h" #include "debug.h" @@ -41,6 +42,16 @@ int spi_init() { gpio_fsel(SPI_FLASH_CS_GPIOx, SPI_FLASH_CS_GPIO_PINx, GPIO_FSEL_OUTPUT); gpio_bit_set(SPI_FLASH_CS_GPIOx, SPI_FLASH_CS_GPIO_PINx); +#if defined (SPI_FLASH_WP_GPIO_PINx) + gpio_fsel(SPI_GPIOx, SPI_FLASH_WP_GPIO_PINx, GPIO_FSEL_OUTPUT); + gpio_bit_set(SPI_GPIOx, SPI_FLASH_WP_GPIO_PINx); +#endif + +#if defined (SPI_FLASH_HOLD_GPIO_PINx) + gpio_fsel(SPI_GPIOx, SPI_FLASH_HOLD_GPIO_PINx, GPIO_FSEL_OUTPUT); + gpio_bit_set(SPI_GPIOx, SPI_FLASH_HOLD_GPIO_PINx); +#endif + return 0; } diff --git a/lib-flash/src/spi/get_timer.cpp b/lib-flash/src/spi/get_timer.cpp index 91bc169..3edf77d 100644 --- a/lib-flash/src/spi/get_timer.cpp +++ b/lib-flash/src/spi/get_timer.cpp @@ -2,7 +2,7 @@ * @file get_timer.cpp * */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-flash/src/spi/gigadevice.cpp b/lib-flash/src/spi/gigadevice.cpp old mode 100644 new mode 100755 index d32ec21..9c72f30 --- a/lib-flash/src/spi/gigadevice.cpp +++ b/lib-flash/src/spi/gigadevice.cpp @@ -12,7 +12,7 @@ /* * Original code : https://github.com/martinezjavier/u-boot/blob/master/drivers/mtd/spi/gigadevice.c */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -50,6 +50,11 @@ static constexpr struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] 64, "GD25LQ", }, + { + 0x4015, + 8, + "GD25Q40", + }, { 0x4017, 128, @@ -68,10 +73,11 @@ int spi_flash_probe_gigadevice(struct spi_flash *flash, uint8_t *idcode) { } if (i == ARRAY_SIZE(gigadevice_spi_flash_table)) { - DEBUG_PRINTF("SF: Unsupported Gigadevice ID %02x%02x", idcode[1], idcode[2]); + DEBUG_PRINTF("SF: Unsupported GigaDevice ID %02x%02x", idcode[1], idcode[2]); return -1; } + flash->name = params->name; flash->page_size = 256; flash->sector_size = flash->page_size * 16; flash->size = flash->sector_size * 16 * params->nr_blocks; diff --git a/lib-flash/src/spi/macronix.cpp b/lib-flash/src/spi/macronix.cpp index 3a2ceb2..ebff01c 100644 --- a/lib-flash/src/spi/macronix.cpp +++ b/lib-flash/src/spi/macronix.cpp @@ -19,7 +19,7 @@ /* * Original code : https://github.com/martinezjavier/u-boot/blob/master/drivers/mtd/spi/macronix.c */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-flash/src/spi/spi_flash.cpp b/lib-flash/src/spi/spi_flash.cpp index bcb1579..ab0e11c 100644 --- a/lib-flash/src/spi/spi_flash.cpp +++ b/lib-flash/src/spi/spi_flash.cpp @@ -5,7 +5,7 @@ /* * Original code : https://github.com/martinezjavier/u-boot/blob/master/drivers/mtd/spi/spi_flash.c */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,6 +33,7 @@ #include #include #include +#include #include "spi/spi_flash.h" @@ -90,6 +91,14 @@ static const struct { }; #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN) +static uint32_t get_timer(uint32_t base) { + if (0 == base) { + return static_cast(time(nullptr)); + } + + return static_cast(time(nullptr)) - base; +} + uint32_t spi_flash_get_size() { return s_flash.size; } @@ -356,7 +365,7 @@ int spi_flash_cmd_write_status(uint8_t sr) { return 0; } -int spi_flash_probe(__attribute__((unused)) unsigned int cs, __attribute__((unused)) unsigned int max_hz, __attribute__((unused)) unsigned int spi_mode) { +int spi_flash_probe([[maybe_unused]] unsigned int cs, [[maybe_unused]] unsigned int max_hz, [[maybe_unused]] unsigned int spi_mode) { int shift; unsigned i; uint8_t idcode[IDCODE_LEN] = {0, }; diff --git a/lib-flash/src/spi/spi_flash_internal.h b/lib-flash/src/spi/spi_flash_internal.h index 6b6af84..019fff1 100644 --- a/lib-flash/src/spi/spi_flash_internal.h +++ b/lib-flash/src/spi/spi_flash_internal.h @@ -2,7 +2,7 @@ * @file spi_internal.h * */ -/* Copyright (C) 2019-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2019-2024 by Arjan van Vught mailto:info@g32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -74,18 +74,16 @@ struct spi_flash { #define SPI_XFER_SPEED_HZ 6000000 ///< 6MHz -extern uint32_t get_timer(uint32_t base); //TODO Remove - extern int spi_init(); extern int spi_xfer(uint32_t bitlen, const uint8_t *dout, uint8_t *din, uint32_t flags); -#define CONFIG_SPI_FLASH_MACRONIX -int spi_flash_probe_macronix(struct spi_flash *flash, uint8_t *idcode); +//#define CONFIG_SPI_FLASH_MACRONIX +//int spi_flash_probe_macronix(struct spi_flash *flash, uint8_t *idcode); #define CONFIG_SPI_FLASH_WINBOND extern int spi_flash_probe_winbond(struct spi_flash *spi, uint8_t *idcode); -#define CONFIG_SPI_FLASH_GIGADEVICE -extern int spi_flash_probe_gigadevice(struct spi_flash *spi, uint8_t *idcode); +//#define CONFIG_SPI_FLASH_GIGADEVICE +//extern int spi_flash_probe_gigadevice(struct spi_flash *spi, uint8_t *idcode); #endif /* SPI_FLASH_INTERNAL_H_ */ diff --git a/lib-flash/src/spi/winbond.cpp b/lib-flash/src/spi/winbond.cpp index 249308d..e821a3c 100644 --- a/lib-flash/src/spi/winbond.cpp +++ b/lib-flash/src/spi/winbond.cpp @@ -10,7 +10,7 @@ /* * Original code : https://github.com/martinezjavier/u-boot/blob/master/drivers/mtd/spi/winbond.c */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-flashcode/.cproject b/lib-flashcode/.cproject index 6f31120..0aa5b9c 100755 --- a/lib-flashcode/.cproject +++ b/lib-flashcode/.cproject @@ -5,7 +5,7 @@ - + @@ -14,15 +14,87 @@ - + - - @@ -105,7 +187,6 @@ - @@ -117,7 +198,11 @@ - + + + + + @@ -125,16 +210,22 @@ - + + + + + + + - + - + diff --git a/lib-flashcode/Makefile.GD32 b/lib-flashcode/Makefile.GD32 index e0ac745..3808855 100755 --- a/lib-flashcode/Makefile.GD32 +++ b/lib-flashcode/Makefile.GD32 @@ -4,7 +4,11 @@ ifneq ($(MAKE_FLAGS),) ifeq ($(findstring gd32f4xx,$(FAMILY)), gd32f4xx) EXTRA_SRCDIR=src/gd32/f4xx else - EXTRA_SRCDIR=src/gd32/fmc + ifeq ($(findstring gd32h7xx,$(FAMILY)), gd32h7xx) + EXTRA_SRCDIR=src/gd32/h7xx + else + EXTRA_SRCDIR=src/gd32/fmc + endif endif else EXTRA_SRCDIR=src/gd32/fmc diff --git a/lib-flashcode/include/flashcode.h b/lib-flashcode/include/flashcode.h index 95eacb7..de55e14 100644 --- a/lib-flashcode/include/flashcode.h +++ b/lib-flashcode/include/flashcode.h @@ -2,7 +2,7 @@ * @file flashcode.h * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-flashcode/src/gd32/flashcode.cpp b/lib-flashcode/src/gd32/flashcode.cpp index 449e416..f423d04 100644 --- a/lib-flashcode/src/gd32/flashcode.cpp +++ b/lib-flashcode/src/gd32/flashcode.cpp @@ -2,7 +2,7 @@ * @file flashcode.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,7 +41,7 @@ FlashCode::FlashCode() { m_IsDetected = true; - printf("FMC: Detected %s with total %d bytes [%d kB]\n", GetName(), GetSize(), GetSize() / 1024U); + printf("FMC: %s %u [%u]\n", GetName(), static_cast(GetSize()), static_cast(GetSize() / 1024U)); DEBUG_EXIT } diff --git a/lib-flashcode/src/gd32/fmc/flashcode.cpp b/lib-flashcode/src/gd32/h7xx/flashcode.cpp similarity index 57% rename from lib-flashcode/src/gd32/fmc/flashcode.cpp rename to lib-flashcode/src/gd32/h7xx/flashcode.cpp index 9338ba5..47cc26a 100644 --- a/lib-flashcode/src/gd32/fmc/flashcode.cpp +++ b/lib-flashcode/src/gd32/h7xx/flashcode.cpp @@ -2,7 +2,7 @@ * @file flashcode.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ #include #include +#include #include #include "flashcode.h" @@ -36,8 +37,6 @@ namespace flashcode { /* Backwards compatibility with SPI FLASH */ static constexpr auto FLASH_SECTOR_SIZE = 4096U; -/* The flash page size is 2KB for bank0 */ -static constexpr auto BANK0_FLASH_PAGE = (2U * 1024U); /* The flash page size is 4KB for bank1 */ static constexpr auto BANK1_FLASH_PAGE = (4U * 1024U); @@ -55,30 +54,17 @@ static uint32_t s_nPage; static uint32_t s_nLength; static uint32_t s_nAddress; static uint32_t *s_pData; -static bool s_isBank0; } // namespace flashcode -bool static is_bank0(const uint32_t page_address) { - /* flash size is greater than 512k */ - if (FMC_BANK0_SIZE < FMC_SIZE) { - if (FMC_BANK0_END_ADDRESS > page_address) { - return true; - } else { - return false; - } - } - - return true; -} - using namespace flashcode; uint32_t FlashCode::GetSize() const { - return FMC_SIZE * 1024U; + const auto FLASH_DENSITY = ((REG32(0x1FF0F7E0) >> 16) & 0xFFFF) * 1024U; + return FLASH_DENSITY; } uint32_t FlashCode::GetSectorSize() const { - return FLASH_SECTOR_SIZE; + return flashcode::FLASH_SECTOR_SIZE; } bool FlashCode::Read(uint32_t nOffset, uint32_t nLength, uint8_t *pBuffer, flashcode::result& nResult) { @@ -93,7 +79,7 @@ bool FlashCode::Read(uint32_t nOffset, uint32_t nLength, uint8_t *pBuffer, flash nLength -= 4; } - nResult = result::OK; + nResult = flashcode::result::OK; DEBUG_EXIT return true; @@ -109,42 +95,20 @@ bool FlashCode::Erase(uint32_t nOffset, uint32_t nLength, flashcode::result& nRe case State::IDLE: s_nPage = nOffset + FLASH_BASE; s_nLength = nLength; - if ((s_isBank0 = is_bank0(s_nPage))) { - fmc_bank0_unlock(); - } else { - fmc_bank1_unlock(); - } + fmc_unlock(); s_State = State::ERASE_BUSY; - DEBUG_PRINTF("isBank0=%d", static_cast(s_isBank0)); DEBUG_EXIT return false; break; case State::ERASE_BUSY: - if (s_isBank0) { - if (FMC_BUSY == fmc_bank0_state_get()) { - DEBUG_EXIT - return false; - } - } else { - if (FMC_BUSY == fmc_bank1_state_get()) { - DEBUG_EXIT - return false; - } - } - - if (s_isBank0) { - FMC_CTL0 &= ~FMC_CTL0_PER; - } else { - FMC_CTL1 &= ~FMC_CTL1_PER; + if (SET == fmc_flag_get(FMC_FLAG_BUSY)) { + DEBUG_EXIT + return false; } if (s_nLength == 0) { - if (s_isBank0) { - fmc_bank0_lock(); - } else { - fmc_bank1_lock(); - } s_State = State::IDLE; + fmc_lock(); DEBUG_EXIT return true; } @@ -157,43 +121,16 @@ bool FlashCode::Erase(uint32_t nOffset, uint32_t nLength, flashcode::result& nRe if (s_nLength > 0) { DEBUG_PRINTF("s_nPage=%p", s_nPage); - if (s_isBank0) { - FMC_CTL0 |= FMC_CTL0_PER; - FMC_ADDR0 = s_nPage; - FMC_CTL0 |= FMC_CTL0_START; + fmc_sector_erase(s_nPage); - s_nLength -= BANK0_FLASH_PAGE; - s_nPage += BANK0_FLASH_PAGE; - } else { - FMC_CTL1 |= FMC_CTL1_PER; - FMC_ADDR1 = s_nPage; - if (FMC_OBSTAT & FMC_OBSTAT_SPC) { - FMC_ADDR0 = s_nPage; - } - FMC_CTL1 |= FMC_CTL1_START; - - s_nLength -= BANK1_FLASH_PAGE; - s_nPage += BANK1_FLASH_PAGE; - } + s_nLength -= BANK1_FLASH_PAGE; + s_nPage += BANK1_FLASH_PAGE; } s_State = State::ERASE_BUSY; DEBUG_EXIT return false; break; - case State::WRITE_BUSY: - if (s_isBank0) { - FMC_CTL0 &= ~FMC_CTL0_PG; - } else { - FMC_CTL1 &= ~FMC_CTL1_PG; - } - /*@fallthrough@*/ - /* no break */ - case State::WRITE_PROGRAM: - s_State = State::IDLE; - DEBUG_EXIT - return false; - break; default: assert(0); __builtin_unreachable(); @@ -206,91 +143,66 @@ bool FlashCode::Erase(uint32_t nOffset, uint32_t nLength, flashcode::result& nRe } bool FlashCode::Write(uint32_t nOffset, uint32_t nLength, const uint8_t *pBuffer, flashcode::result& nResult) { + if ((s_State == flashcode::State::WRITE_PROGRAM) || (s_State == flashcode::State::WRITE_BUSY)) { + } else { + DEBUG_ENTRY + } nResult = result::OK; switch (s_State) { - case State::IDLE: + case flashcode::State::IDLE: DEBUG_PUTS("State::IDLE"); - s_nAddress = nOffset + FLASH_BASE; + flashcode::s_nAddress = nOffset + FLASH_BASE; s_pData = const_cast(reinterpret_cast(pBuffer)); s_nLength = nLength; - if ((s_isBank0 = is_bank0(s_nAddress))) { - fmc_bank0_unlock(); - } else { - fmc_bank1_unlock(); - } + fmc_unlock(); s_State = State::WRITE_BUSY; - DEBUG_PRINTF("isBank0=%d", static_cast(s_isBank0)); DEBUG_EXIT return false; break; - case State::WRITE_BUSY: - if (s_isBank0) { - if (FMC_BUSY == fmc_bank0_state_get()) { - DEBUG_EXIT - return false; - } - } else { - if (FMC_BUSY == fmc_bank1_state_get()) { - DEBUG_EXIT - return false; - } - } - - if (s_isBank0) { - FMC_CTL0 &= ~FMC_CTL0_PG; - } else { - FMC_CTL1 &= ~FMC_CTL1_PG; + case flashcode::State::WRITE_BUSY: + if (SET == fmc_flag_get(FMC_FLAG_BUSY)) { + DEBUG_EXIT + return false; } if (s_nLength == 0) { - if (s_isBank0) { - fmc_bank0_lock(); + fmc_lock(); + s_State = State::IDLE; + + if( memcmp(reinterpret_cast(nOffset + FLASH_BASE), pBuffer, nLength) == 0) { + DEBUG_PUTS("memcmp OK"); } else { - fmc_bank1_lock(); + DEBUG_PUTS("memcmp failed"); } - s_State = State::IDLE; + DEBUG_EXIT return true; } - s_State = State::WRITE_PROGRAM; + s_State = flashcode::State::WRITE_PROGRAM; return false; break; - case State::WRITE_PROGRAM: + case flashcode::State::WRITE_PROGRAM: if (s_nLength >= 4) { - if (s_isBank0) { - FMC_CTL0 |= FMC_CTL0_PG; - } else { - FMC_CTL1 |= FMC_CTL1_PG; + if (FMC_READY == fmc_ready_wait(0xFF)) { + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + __ISB(); + __DSB(); + REG32(s_nAddress) = *s_pData; + __ISB(); + __DSB(); + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + s_pData++; + s_nAddress += 4; + s_nLength -= 4; } - REG32(s_nAddress) = *s_pData; - - s_pData++; - s_nAddress += 4; - s_nLength -= 4; } else if (s_nLength > 0) { - if (s_isBank0) { - FMC_CTL0 |= FMC_CTL0_PG; - } else { - FMC_CTL1 |= FMC_CTL1_PG; - } - REG32(s_nAddress) = *s_pData; - } - s_State = State::WRITE_BUSY; - return false; - break; - case State::ERASE_BUSY: - if (s_isBank0) { - FMC_CTL0 &= ~FMC_CTL0_PER; - } else { - FMC_CTL1 &= ~FMC_CTL1_PER; + DEBUG_PUTS("Error!"); } - /*@fallthrough@*/ - /* no break */ - case State::ERASE_PROGAM: - s_State = State::IDLE; - DEBUG_EXIT + s_State = flashcode::State::WRITE_BUSY; return false; break; default: diff --git a/lib-flashcodeinstall/.cproject b/lib-flashcodeinstall/.cproject index 4cd7f75..d84c009 100755 --- a/lib-flashcodeinstall/.cproject +++ b/lib-flashcodeinstall/.cproject @@ -33,19 +33,15 @@ - @@ -61,19 +57,15 @@ - @@ -97,7 +89,6 @@ - @@ -134,4 +125,5 @@ + \ No newline at end of file diff --git a/lib-flashcodeinstall/.settings/language.settings.xml b/lib-flashcodeinstall/.settings/language.settings.xml index 87c6534..3d1249b 100755 --- a/lib-flashcodeinstall/.settings/language.settings.xml +++ b/lib-flashcodeinstall/.settings/language.settings.xml @@ -2,10 +2,13 @@ + + + + - diff --git a/lib-flashcodeinstall/Makefile.H3 b/lib-flashcodeinstall/Makefile.H3 deleted file mode 100755 index 7b71798..0000000 --- a/lib-flashcodeinstall/Makefile.H3 +++ /dev/null @@ -1,9 +0,0 @@ -DEFINES=NDEBUG - -EXTRA_INCLUDES=../lib-flashcodeinstall/src/params ../lib-properties/include - -EXTRA_SRCDIR=src/params - -include Rules.mk -include ../firmware-template-h3/lib/Rules.mk - diff --git a/lib-flashcodeinstall/Rules.mk b/lib-flashcodeinstall/Rules.mk old mode 100755 new mode 100644 index 7f2a5a1..ef90a18 --- a/lib-flashcodeinstall/Rules.mk +++ b/lib-flashcodeinstall/Rules.mk @@ -1,3 +1,3 @@ EXTRA_SRCDIR+= -EXTRA_INCLUDES+=../lib-flashcode/include ../lib-hal/include ../lib-display/include \ No newline at end of file +EXTRA_INCLUDES+=../lib-flashcode/include ../lib-display/include \ No newline at end of file diff --git a/lib-flashcodeinstall/include/flashcodeinstall.h b/lib-flashcodeinstall/include/flashcodeinstall.h old mode 100755 new mode 100644 index 78b77f8..1a0cb88 --- a/lib-flashcodeinstall/include/flashcodeinstall.h +++ b/lib-flashcodeinstall/include/flashcodeinstall.h @@ -2,7 +2,7 @@ * @file flashcodeinstall.h * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,9 +26,6 @@ #ifndef FLASHCODEINSTALL_H_ #define FLASHCODEINSTALL_H_ -#include -#include - #if defined (H3) // nuc-i5:~/uboot-spi/u-boot$ grep CONFIG_BOOTCOMMAND include/configs/sunxi-common.h // #define CONFIG_BOOTCOMMAND "sf probe; sf read 48000000 180000 22000; bootm 48000000" @@ -38,34 +35,51 @@ #elif defined (GD32) # if defined (BOARD_GD32F107RC) # define OFFSET_UIMAGE 0x007000 // 28K -# define FIRMWARE_MAX_SIZE (74 * 1024) // 74K +# define FIRMWARE_MAX_SIZE (76 * 1024) // 76K # elif defined (BOARD_GD32F207RG) # define OFFSET_UIMAGE 0x008000 // 32K # define FIRMWARE_MAX_SIZE (234 * 1024) // 234K -# elif defined (BOARD_GD32F207VC) +# elif defined (BOARD_GD32F207VC_2) +# define OFFSET_UIMAGE 0x008000 // 32K +# define FIRMWARE_MAX_SIZE (106 * 1024) // 106K +# elif defined (BOARD_GD32F207VC_4) # define OFFSET_UIMAGE 0x008000 // 32K # define FIRMWARE_MAX_SIZE (106 * 1024) // 106K # elif defined (BOARD_GD32F207C_EVAL) -# define OFFSET_UIMAGE 0x007000 // 28K +# define OFFSET_UIMAGE 0x008000 // 32K # define FIRMWARE_MAX_SIZE (106 * 1024) // 106K # elif defined (BOARD_GD32F407RE) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (106 * 1024) // 106K +# define FIRMWARE_MAX_SIZE (116 * 1024) // 116K # elif defined (BOARD_BW_OPIDMX4) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (106 * 1024) // 106K +# define FIRMWARE_MAX_SIZE (116 * 1024) // 116K +# elif defined (BOARD_DMX3) +# define OFFSET_UIMAGE 0x008000 // 32K +# define FIRMWARE_MAX_SIZE (116 * 1024) // 116K # elif defined (BOARD_DMX4) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (106 * 1024) // 106K +# define FIRMWARE_MAX_SIZE (116 * 1024) // 116K # elif defined (BOARD_GD32F450VE) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (168 * 1024) // 168K +# define FIRMWARE_MAX_SIZE (180 * 1024) // 180K # elif defined (BOARD_GD32F450VI) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (224 * 1024) // 224K +# define FIRMWARE_MAX_SIZE (234 * 1024) // 234K # elif defined (BOARD_16X4U_PIXEL) # define OFFSET_UIMAGE 0x008000 // 32K -# define FIRMWARE_MAX_SIZE (224 * 1024) // 224K +# define FIRMWARE_MAX_SIZE (234 * 1024) // 234K +# elif defined (BOARD_GD32F470VG) +# define OFFSET_UIMAGE 0x008000 // 32K +# define FIRMWARE_MAX_SIZE (234 * 1024) // 234K +# elif defined (BOARD_GD32F470Z_EVAL) +# define OFFSET_UIMAGE 0x008000 // 32K +# define FIRMWARE_MAX_SIZE (175 * 1024) // 175K +# elif defined (BOARD_GD32H759I_EVAL) +# define OFFSET_UIMAGE 0x008000 // 32K +# define FIRMWARE_MAX_SIZE (300 * 1024) // 300K +# else +# error Board is not supported # endif #else # define OFFSET_UIMAGE 0x0 @@ -73,6 +87,9 @@ #ifdef __cplusplus +#include +#include + #include "flashcode.h" class FlashCodeInstall: FlashCode { diff --git a/lib-flashcodeinstall/src/flashcodeinstall.cpp b/lib-flashcodeinstall/src/flashcodeinstall.cpp old mode 100755 new mode 100644 index 370d192..f3018b2 --- a/lib-flashcodeinstall/src/flashcodeinstall.cpp +++ b/lib-flashcodeinstall/src/flashcodeinstall.cpp @@ -2,7 +2,7 @@ * @file flashcodeinstall.cpp * */ -/* Copyright (C) 2018-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,10 +39,10 @@ bool FlashCodeInstall::WriteFirmware(const uint8_t *pBuffer, uint32_t nSize) { assert(pBuffer != nullptr); assert(nSize != 0); - DEBUG_PRINTF("(%p + %p)=%p, m_nFlashSize=%d", OFFSET_UIMAGE, nSize, (OFFSET_UIMAGE + nSize), m_nFlashSize); + DEBUG_PRINTF("(%p + %p)=%p, m_nFlashSize=%u", OFFSET_UIMAGE, nSize, (OFFSET_UIMAGE + nSize), static_cast(m_nFlashSize)); if ((OFFSET_UIMAGE + nSize) > m_nFlashSize) { - printf("error: flash size %d > %d\n", (OFFSET_UIMAGE + nSize), m_nFlashSize); + printf("error: flash size %u > %u\n", static_cast(OFFSET_UIMAGE + nSize), static_cast(m_nFlashSize)); DEBUG_EXIT return false; } @@ -60,20 +60,20 @@ bool FlashCodeInstall::WriteFirmware(const uint8_t *pBuffer, uint32_t nSize) { DEBUG_PRINTF("nSize=%x, nSectorSize=%x, nEraseSize=%x", nSize, nSectorSize, nEraseSize); - Display::Get()->TextStatus("Erase", Display7SegmentMessage::INFO_SPI_ERASE, CONSOLE_GREEN); + Display::Get()->TextStatus("Erase", CONSOLE_GREEN); flashcode::result nResult; - FlashCode::Erase(OFFSET_UIMAGE, nEraseSize, nResult); + while(!FlashCode::Erase(OFFSET_UIMAGE, nEraseSize, nResult)); if (flashcode::result::ERROR == nResult) { puts("error: flash erase"); return false; } - Display::Get()->TextStatus("Writing", Display7SegmentMessage::INFO_SPI_WRITING, CONSOLE_GREEN); + Display::Get()->TextStatus("Writing", CONSOLE_GREEN); - FlashCode::Write(OFFSET_UIMAGE, nSize, pBuffer, nResult); + while(!FlashCode::Write(OFFSET_UIMAGE, nSize, pBuffer, nResult)); if (flashcode::result::ERROR == nResult) { puts("error: flash write"); @@ -84,7 +84,7 @@ bool FlashCodeInstall::WriteFirmware(const uint8_t *pBuffer, uint32_t nSize) { Hardware::Get()->WatchdogInit(); } - Display::Get()->TextStatus("Done", Display7SegmentMessage::INFO_SPI_DONE, CONSOLE_GREEN); + Display::Get()->TextStatus("Done", CONSOLE_GREEN); DEBUG_EXIT return true; diff --git a/lib-gd32/.cproject b/lib-gd32/.cproject index 6102092..c0d2882 100644 --- a/lib-gd32/.cproject +++ b/lib-gd32/.cproject @@ -14,7 +14,7 @@ - + diff --git a/lib-gd32/Makefile.GD32 b/lib-gd32/Makefile.GD32 index 3bbe2a4..a3896d5 100644 --- a/lib-gd32/Makefile.GD32 +++ b/lib-gd32/Makefile.GD32 @@ -1,79 +1,87 @@ +$(info "lib-gd32/Makefile.GD32") $(info $$FAMILY [${FAMILY}]) +$(info $$MAKE_FLAGS [${MAKE_FLAGS}]) -ifeq ($(FAMILY),) - FAMILY=gd32f20x -endif - -$(info $$FAMILY [${FAMILY}]) +DEFINES=NDEBUG -ifeq ($(findstring gd32f10x,$(FAMILY)), gd32f10x) - EXTRA_SRCDIR=gd32f10x/CMSIS/GD/GD32F10x/Source - EXTRA_SRCDIR+=gd32f10x/GD32F10x_standard_peripheral/Source -endif +EXTRA_SRCDIR= -ifeq ($(findstring gd32f20x,$(FAMILY)), gd32f20x) - EXTRA_SRCDIR=gd32f20x/CMSIS/GD/GD32F20x/Source - EXTRA_SRCDIR+=gd32f20x/GD32F20x_standard_peripheral/Source - ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) - EXTRA_SRCDIR+=gd32f20x/GD32F20x_usbfs_library/host/core/Source - - EXTRA_C_SOURCE_FILES=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usb_core.c - EXTRA_C_SOURCE_FILES+=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usb_host.c - EXTRA_C_SOURCE_FILES+=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usbh_int.c - - EXTRA_INCLUDES+=gd32f20x/GD32F20x_usbfs_library/driver/Include - EXTRA_INCLUDES+=gd32f20x/GD32F20x_usbfs_library/host/core/Include - EXTRA_INCLUDES+=gd32f20x/GD32F20x_usbfs_library/ustd/common - - ifeq ($(findstring CONFIG_USB_HOST_MSC,$(MAKE_FLAGS)), CONFIG_USB_HOST_MSC) - EXTRA_SRCDIR+=gd32f20x/GD32F20x_usbfs_library/host/class/msc/Source - - EXTRA_INCLUDES+=gd32f20x/GD32F20x_usbfs_library/host/class/msc/Include - EXTRA_INCLUDES+=gd32f20x/GD32F20x_usbfs_library/ustd/class/msc - - EXTRA_INCLUDES+=../lib-hal/ff12c - endif - - endif -endif +ifneq ($(MAKE_FLAGS),) + ifeq ($(findstring CONFIG_HAL_USE_SYSTICK,$(MAKE_FLAGS)), CONFIG_HAL_USE_SYSTICK) + EXTRA_SRCDIR+=src/systick + endif -ifeq ($(findstring gd32f30x,$(FAMILY)), gd32f30x) - EXTRA_SRCDIR=gd32f30x/CMSIS/GD/GD32F30x/Source - EXTRA_SRCDIR+=gd32f30x/GD32F30x_standard_peripheral/Source -endif + ifeq ($(findstring gd32f10x,$(FAMILY)), gd32f10x) + EXTRA_SRCDIR+=gd32f10x/CMSIS/GD/GD32F10x/Source + EXTRA_SRCDIR+=gd32f10x/GD32F10x_standard_peripheral/Source + EXTRA_SRCDIR+=src/f + endif -ifeq ($(findstring gd32f4xx,$(FAMILY)), gd32f4xx) - EXTRA_SRCDIR=gd32f4xx/CMSIS/GD/GD32F4xx/Source - EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_standard_peripheral/Source - ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) - EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_usb_library/host/core/Source + ifeq ($(findstring gd32f20x,$(FAMILY)), gd32f20x) + EXTRA_SRCDIR+=gd32f20x/CMSIS/GD/GD32F20x/Source + EXTRA_SRCDIR+=gd32f20x/GD32F20x_standard_peripheral/Source - EXTRA_C_SOURCE_FILES=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usb_core.c - EXTRA_C_SOURCE_FILES+=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usb_host.c - EXTRA_C_SOURCE_FILES+=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usbh_int.c - - EXTRA_INCLUDES+=gd32f4xx/GD32F4xx_usb_library/driver/Include - EXTRA_INCLUDES+=gd32f4xx/GD32F4xx_usb_library/host/core/Include - EXTRA_INCLUDES+=gd32f4xx/GD32F4xx_usb_library/ustd/common - - ifeq ($(findstring CONFIG_USB_HOST_MSC,$(MAKE_FLAGS)), CONFIG_USB_HOST_MSC) - EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_usb_library/host/class/msc/Source - - EXTRA_INCLUDES+=gd32f4xx/GD32F4xx_usb_library/host/class/msc/Include - EXTRA_INCLUDES+=gd32f4xx/GD32F4xx_usb_library/ustd/class/msc - - EXTRA_INCLUDES+=../lib-hal/ff12c - endif - - endif -endif + ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) + EXTRA_SRCDIR+=device/usb/f + EXTRA_SRCDIR+=gd32f20x/GD32F20x_usbfs_library/host/core/Source + EXTRA_C_SOURCE_FILES=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usb_core.c + EXTRA_C_SOURCE_FILES+=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usb_host.c + EXTRA_C_SOURCE_FILES+=gd32f20x/GD32F20x_usbfs_library/driver/Source/drv_usbh_int.c + + ifeq ($(findstring CONFIG_USB_HOST_MSC,$(MAKE_FLAGS)), CONFIG_USB_HOST_MSC) + EXTRA_SRCDIR+=gd32f20x/GD32F20x_usbfs_library/host/class/msc/Source + endif + endif + EXTRA_SRCDIR+=src/f + endif -$(info $$MAKE_FLAGS [${MAKE_FLAGS}]) + ifeq ($(findstring gd32f30x,$(FAMILY)), gd32f30x) + EXTRA_SRCDIR+=gd32f30x/CMSIS/GD/GD32F30x/Source + EXTRA_SRCDIR+=gd32f30x/GD32F30x_standard_peripheral/Source + EXTRA_SRCDIR+=src/f + endif + + ifeq ($(findstring gd32f4xx,$(FAMILY)), gd32f4xx) + EXTRA_SRCDIR+=gd32f4xx/CMSIS/GD/GD32F4xx/Source + EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_standard_peripheral/Source + + ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) + EXTRA_SRCDIR+=device/usb/f + EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_usb_library/host/core/Source + EXTRA_C_SOURCE_FILES=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usb_core.c + EXTRA_C_SOURCE_FILES+=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usb_host.c + EXTRA_C_SOURCE_FILES+=gd32f4xx/GD32F4xx_usb_library/driver/Source/drv_usbh_int.c + + ifeq ($(findstring CONFIG_USB_HOST_MSC,$(MAKE_FLAGS)), CONFIG_USB_HOST_MSC) + EXTRA_SRCDIR+=gd32f4xx/GD32F4xx_usb_library/host/class/msc/Source + endif + endif + EXTRA_SRCDIR+=src/f + endif + + ifeq ($(findstring gd32h7xx,$(FAMILY)), gd32h7xx) + EXTRA_SRCDIR+=gd32h7xx/CMSIS/GD/GD32H7xx/Source + EXTRA_SRCDIR+=gd32h7xx/GD32H7xx_standard_peripheral/Source + + ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) + EXTRA_SRCDIR+=device/usb/h + EXTRA_SRCDIR+=gd32h7xx/GD32H7xx_usbhs_library/host/core/Source + EXTRA_C_SOURCE_FILES=gd32h7xx/GD32H7xx_usbhs_library/driver/Source/drv_usb_core.c + EXTRA_C_SOURCE_FILES+=gd32h7xx/GD32H7xx_usbhs_library/driver/Source/drv_usb_host.c + EXTRA_C_SOURCE_FILES+=gd32h7xx/GD32H7xx_usbhs_library/driver/Source/drv_usbh_int.c + + ifeq ($(findstring CONFIG_USB_HOST_MSC,$(MAKE_FLAGS)), CONFIG_USB_HOST_MSC) + EXTRA_SRCDIR+=gd32h7xx/GD32H7xx_usbhs_library/host/class/msc/Source + endif + endif + EXTRA_SRCDIR+=src/h + endif -ifneq ($(MAKE_FLAGS),) ifeq ($(findstring NO_EMAC,$(MAKE_FLAGS)), NO_EMAC) else - EXTRA_SRCDIR+=device/emac + ifeq ($(findstring CONFIG_ENET_ENABLE_PTP,$(MAKE_FLAGS)), CONFIG_ENET_ENABLE_PTP) + EXTRA_SRCDIR+=src/ptp + endif endif ifeq ($(findstring CONFIG_USE_SOFTUART0,$(MAKE_FLAGS)), CONFIG_USE_SOFTUART0) @@ -85,19 +93,60 @@ ifneq ($(MAKE_FLAGS),) endif endif - ifeq ($(findstring ENABLE_PHY_SWITCH,$(MAKE_FLAGS)), ENABLE_PHY_SWITCH) - EXTRA_SRCDIR+=device/emac/dsa - endif - ifeq ($(findstring ENABLE_USB_HOST,$(MAKE_FLAGS)), ENABLE_USB_HOST) EXTRA_SRCDIR+=device/usb - endif + endif + + ifeq ($(findstring USE_FREE_RTOS,$(MAKE_FLAGS)), USE_FREE_RTOS) + EXTRA_SRCDIR+=FreeRTOS/FreeRTOS-Kernel + EXTRA_SRCDIR+=FreeRTOS/FreeRTOS-Kernel/portable/Common + ifeq ($(findstring ARM_CM3,$(MAKE_FLAGS)), ARM_CM3) +# EXTRA_SRCDIR+=FreeRTOS/FreeRTOS-Kernel/portable/GCC/ARM_CM3 + endif + ifeq ($(findstring ARM_CM3,$(MAKE_FLAGS)), ARM_CM4F) + # EXTRA_SRCDIR+=FreeRTOS/FreeRTOS-Kernel/portable/GCC/ARM_CM4F + endif + ifeq ($(findstring ARM_CM3,$(MAKE_FLAGS)), ARM_CM7) + # EXTRA_SRCDIR+=FreeRTOS/FreeRTOS-Kernel/portable/GCC/ARM_CM7/r0p1 + endif + endif else - EXTRA_SRCDIR+=device/emac device/emac/dsa + ifeq ($(FAMILY),) + ifneq (, $(shell test -d '../lib-gd32/gd32f10x' && echo -n yes)) + FAMILY=gd32f10x + EXTRA_SRCDIR+=src/f + endif + ifneq (, $(shell test -d '../lib-gd32/gd32f20x' && echo -n yes)) + FAMILY=gd32f20x + HAVE_SOFTUART=1 + # EXTRA_SRCDIR+=src/f + endif + ifneq (, $(shell test -d '../lib-gd32/gd32f30x' && echo -n yes)) + FAMILY=gd32f30x +# EXTRA_SRCDIR+=src/f + endif + ifneq (, $(shell test -d '../lib-gd32/gd32f4xx' && echo -n yes)) + FAMILY=gd32f4xx + HAVE_SOFTUART=1 +# EXTRA_SRCDIR+=src/f + endif + ifneq (, $(shell test -d '../lib-gd32/gd32h7xx' && echo -n yes)) + FAMILY=gd32h7xx + HAVE_SOFTUART=1 +# EXTRA_SRCDIR+=src/h + endif + endif + + EXTRA_SRCDIR+=device/emac EXTRA_SRCDIR+=device/usb - EXTRA_SRCDIR+=src/uart0 src/softuart0 + EXTRA_SRCDIR+=src/uart0 + ifdef HAVE_SOFTUART + EXTRA_SRCDIR+=src/softuart0 + endif DEFINES=ENABLE_USB_HOST CONFIG_USB_HOST_MSC endif +$(info $$FAMILY [${FAMILY}]) + include ../firmware-template-gd32/lib/Rules.mk \ No newline at end of file diff --git a/lib-gd32/gd32f4xx/CMSIS/core_cm4.h b/lib-gd32/gd32f4xx/CMSIS/core_cm4.h deleted file mode 100644 index f319458..0000000 --- a/lib-gd32/gd32f4xx/CMSIS/core_cm4.h +++ /dev/null @@ -1,1790 +0,0 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V3.30 - * @date 17. February 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form 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. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M4 - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) /* Cosmic */ - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ -#include /* Compiler specific SIMD Intrinsics */ - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000 - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_M4 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ - -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register */ -#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register */ -#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register */ -#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ -} - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ -/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ - NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if(IRQn < 0) { - SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if(IRQn < 0) { - return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - return ( - ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | - ((SubPriority & ((1 << (SubPriorityBits )) - 1))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); - *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = ticks - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ - (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = (uint8_t) ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ - -#ifdef __cplusplus -} -#endif diff --git a/lib-gd32/gd32f4xx/CMSIS/core_cm4_simd.h b/lib-gd32/gd32f4xx/CMSIS/core_cm4_simd.h deleted file mode 100644 index bee997e..0000000 --- a/lib-gd32/gd32f4xx/CMSIS/core_cm4_simd.h +++ /dev/null @@ -1,697 +0,0 @@ -/**************************************************************************//** - * @file core_cm4_simd.h - * @brief CMSIS Cortex-M4 SIMD Header File - * @version V3.30 - * @date 17. February 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form 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. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM4_SIMD_H -#define __CORE_CM4_SIMD_H - -#ifdef __cplusplus - extern "C" { -#endif - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ -#define __SADD8 __sadd8 -#define __QADD8 __qadd8 -#define __SHADD8 __shadd8 -#define __UADD8 __uadd8 -#define __UQADD8 __uqadd8 -#define __UHADD8 __uhadd8 -#define __SSUB8 __ssub8 -#define __QSUB8 __qsub8 -#define __SHSUB8 __shsub8 -#define __USUB8 __usub8 -#define __UQSUB8 __uqsub8 -#define __UHSUB8 __uhsub8 -#define __SADD16 __sadd16 -#define __QADD16 __qadd16 -#define __SHADD16 __shadd16 -#define __UADD16 __uadd16 -#define __UQADD16 __uqadd16 -#define __UHADD16 __uhadd16 -#define __SSUB16 __ssub16 -#define __QSUB16 __qsub16 -#define __SHSUB16 __shsub16 -#define __USUB16 __usub16 -#define __UQSUB16 __uqsub16 -#define __UHSUB16 __uhsub16 -#define __SASX __sasx -#define __QASX __qasx -#define __SHASX __shasx -#define __UASX __uasx -#define __UQASX __uqasx -#define __UHASX __uhasx -#define __SSAX __ssax -#define __QSAX __qsax -#define __SHSAX __shsax -#define __USAX __usax -#define __UQSAX __uqsax -#define __UHSAX __uhsax -#define __USAD8 __usad8 -#define __USADA8 __usada8 -#define __SSAT16 __ssat16 -#define __USAT16 __usat16 -#define __UXTB16 __uxtb16 -#define __UXTAB16 __uxtab16 -#define __SXTB16 __sxtb16 -#define __SXTAB16 __sxtab16 -#define __SMUAD __smuad -#define __SMUADX __smuadx -#define __SMLAD __smlad -#define __SMLADX __smladx -#define __SMLALD __smlald -#define __SMLALDX __smlaldx -#define __SMUSD __smusd -#define __SMUSDX __smusdx -#define __SMLSD __smlsd -#define __SMLSDX __smlsdx -#define __SMLSLD __smlsld -#define __SMLSLDX __smlsldx -#define __SEL __sel -#define __QADD __qadd -#define __QSUB __qsub - -#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ - ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) - -#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ - ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) - -#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ - ((int64_t)(ARG3) << 32) ) >> 32)) - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SSAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -#define __USAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) -{ - int32_t result; - - __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* not yet supported */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_SIMD_H */ diff --git a/lib-gd32/gd32f4xx/CMSIS/core_cmFunc.h b/lib-gd32/gd32f4xx/CMSIS/core_cmFunc.h deleted file mode 100644 index adb07b5..0000000 --- a/lib-gd32/gd32f4xx/CMSIS/core_cmFunc.h +++ /dev/null @@ -1,616 +0,0 @@ -/**************************************************************************//** - * @file core_cmFunc.h - * @brief CMSIS Cortex-M Core Function Access Header File - * @version V3.01 - * @date 06. March 2012 - * - * @note - * Copyright (C) 2009-2012 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifndef __CORE_CMFUNC_H -#define __CORE_CMFUNC_H - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ - */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - -/* intrinsic void __enable_irq(); */ -/* intrinsic void __disable_irq(); */ - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__STATIC_INLINE uint32_t __get_CONTROL(void) -{ - register uint32_t __regControl __ASM("control"); - return(__regControl); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__STATIC_INLINE void __set_CONTROL(uint32_t control) -{ - register uint32_t __regControl __ASM("control"); - __regControl = control; -} - - -/** \brief Get IPSR Register - - This function returns the content of the IPSR Register. - - \return IPSR Register value - */ -__STATIC_INLINE uint32_t __get_IPSR(void) -{ - register uint32_t __regIPSR __ASM("ipsr"); - return(__regIPSR); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__STATIC_INLINE uint32_t __get_APSR(void) -{ - register uint32_t __regAPSR __ASM("apsr"); - return(__regAPSR); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__STATIC_INLINE uint32_t __get_xPSR(void) -{ - register uint32_t __regXPSR __ASM("xpsr"); - return(__regXPSR); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__STATIC_INLINE uint32_t __get_PSP(void) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - return(__regProcessStackPointer); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - __regProcessStackPointer = topOfProcStack; -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__STATIC_INLINE uint32_t __get_MSP(void) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - return(__regMainStackPointer); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - __regMainStackPointer = topOfMainStack; -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__STATIC_INLINE uint32_t __get_PRIMASK(void) -{ - register uint32_t __regPriMask __ASM("primask"); - return(__regPriMask); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) -{ - register uint32_t __regPriMask __ASM("primask"); - __regPriMask = (priMask); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __enable_fault_irq __enable_fiq - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -#define __disable_fault_irq __disable_fiq - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -__STATIC_INLINE uint32_t __get_BASEPRI(void) -{ - register uint32_t __regBasePri __ASM("basepri"); - return(__regBasePri); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) -{ - register uint32_t __regBasePri __ASM("basepri"); - __regBasePri = (basePri & 0xff); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -__STATIC_INLINE uint32_t __get_FAULTMASK(void) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - return(__regFaultMask); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - register uint32_t __regFaultMask __ASM("faultmask"); - __regFaultMask = (faultMask & (uint32_t)1); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#endif -} - -#endif /* (__CORTEX_M == 0x04) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ - -#include - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief Enable IRQ Interrupts - - This function enables IRQ interrupts by clearing the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i"); -} - - -/** \brief Disable IRQ Interrupts - - This function disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) -{ - __ASM volatile ("cpsid i"); -} - - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) ); -} - - -/** \brief Get IPSR Register - - This function returns the content of the IPSR Register. - - \return IPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, apsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) -{ - __ASM volatile ("cpsie f"); -} - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) -{ - __ASM volatile ("cpsid f"); -} - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); - return(result); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) ); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - uint32_t result; - - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - return(result); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); -#endif -} - -#endif /* (__CORTEX_M == 0x04) */ - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all instrinsics, - * Including the CMSIS ones. - */ - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - - -#endif /* __CORE_CMFUNC_H */ diff --git a/lib-gd32/gd32f4xx/CMSIS/core_cmInstr.h b/lib-gd32/gd32f4xx/CMSIS/core_cmInstr.h deleted file mode 100644 index 624c175..0000000 --- a/lib-gd32/gd32f4xx/CMSIS/core_cmInstr.h +++ /dev/null @@ -1,618 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V3.01 - * @date 06. March 2012 - * - * @note - * Copyright (C) 2009-2012 ARM Limited. All rights reserved. - * - * @par - * ARM Limited (ARM) is supplying this software for use with Cortex-M - * processor based microcontrollers. This file can be freely distributed - * within development tools that are supporting such ARM based processors. - * - * @par - * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED - * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR - * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. - * - ******************************************************************************/ - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -#define __WFI __wfi - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -#define __WFE __wfe - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -#define __ISB() __isb(0xF) - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -#define __DSB() __dsb(0xF) - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -#define __DMB() __dmb(0xF) - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) -{ - rev16 r0, r0 - bx lr -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -#define __ROR __ror - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __RBIT __rbit - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXW(value, ptr) __strex(value, ptr) - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -#define __CLREX __clrex - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT __ssat - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT __usat - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -#define __CLZ __clz - -#endif /* (__CORTEX_M >= 0x03) */ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ - -#include - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) -{ - __ASM volatile ("isb"); -} - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) -{ - __ASM volatile ("dsb"); -} - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) -{ - __ASM volatile ("dmb"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) -{ - uint32_t result; - - __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) -{ - - __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) ); - return(op1); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief LDR Exclusive (8 bit) - - This function performs a exclusive LDR command for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) -{ - uint8_t result; - - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (16 bit) - - This function performs a exclusive LDR command for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) -{ - uint16_t result; - - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief LDR Exclusive (32 bit) - - This function performs a exclusive LDR command for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); - return(result); -} - - -/** \brief STR Exclusive (8 bit) - - This function performs a exclusive STR command for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (16 bit) - - This function performs a exclusive STR command for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief STR Exclusive (32 bit) - - This function performs a exclusive STR command for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); - return(result); -} - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) -{ - __ASM volatile ("clrex"); -} - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Count leading zeros - - This function counts the number of leading zeros of a data value. - - \param [in] value Value to count the leading zeros - \return number of leading zeros in value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) -{ - uint8_t result; - - __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - -/* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h index 2fbd49b..5dbd094 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h @@ -2,13 +2,11 @@ \file gd32f4xx_adc.h \brief definitions for the ADC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -45,365 +43,365 @@ OF SUCH DAMAGE. #define ADC2 (ADC_BASE + 0x200U) /* registers definitions */ -#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ -#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ -#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ -#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ -#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ -#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ -#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ -#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ -#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ -#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ -#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ -#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC regular sequence register 0 */ -#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */ -#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular sequence register 2 */ -#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ -#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ -#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ -#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ -#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ -#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC regular data register */ -#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x80U) /*!< ADC oversampling control register */ -#define ADC_SSTAT REG32((ADC_BASE) + 0x300U) /*!< ADC summary status register */ -#define ADC_SYNCCTL REG32((ADC_BASE) + 0x304U) /*!< ADC synchronization control register */ -#define ADC_SYNCDATA REG32((ADC_BASE) + 0x308U) /*!< ADC synchronization regular data register */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC routine sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC routine sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC routine sequence register 2 */ +#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC routine data register */ +#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x80U) /*!< ADC oversampling control register */ +#define ADC_SSTAT REG32((ADC_BASE) + 0x300U) /*!< ADC summary status register */ +#define ADC_SYNCCTL REG32((ADC_BASE) + 0x304U) /*!< ADC synchronization control register */ +#define ADC_SYNCDATA REG32((ADC_BASE) + 0x308U) /*!< ADC synchronization routine data register */ /* bits definitions */ /* ADC_STAT */ -#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ -#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ -#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ -#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ -#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ -#define ADC_STAT_ROVF BIT(5) /*!< regular data register overflow */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ +#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< routine channel start flag */ +#define ADC_STAT_ROVF BIT(5) /*!< routine data register overflow */ /* ADC_CTL0 */ -#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ -#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ -#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ -#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ -#define ADC_CTL0_SM BIT(8) /*!< scan mode */ -#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ -#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */ -#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ -#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ -#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ -#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ -#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ -#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ -#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted sequence conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on routine channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on routine channels */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ +#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ /* ADC_CTL1 */ -#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ -#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ -#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ -#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ -#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ -#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */ -#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */ -#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ -#define ADC_CTL1_ETSIC BITS(16,19) /*!< external event select for inserted group */ -#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger conversion mode for inserted channels */ -#define ADC_CTL1_SWICST BIT(22) /*!< start conversion of inserted channels */ -#define ADC_CTL1_ETSRC BITS(24,27) /*!< external event select for regular group */ -#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger conversion mode for regular channels */ -#define ADC_CTL1_SWRCST BIT(30) /*!< start conversion of regular channels */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */ +#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(16,19) /*!< external event select for inserted sequence */ +#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger conversion mode for inserted channels */ +#define ADC_CTL1_SWICST BIT(22) /*!< start conversion of inserted channels */ +#define ADC_CTL1_ETSRC BITS(24,27) /*!< external event select for routine sequence */ +#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger conversion mode for routine channels */ +#define ADC_CTL1_SWRCST BIT(30) /*!< start conversion of routine channels */ /* ADC_SAMPTx x=0..1 */ -#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ /* ADC_IOFFx x=0..3 */ -#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ /* ADC_WDHT */ -#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ /* ADC_WDLT */ -#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ /* ADC_RSQx */ -#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in regular sequence */ -#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in routine sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< routine channel sequence length */ /* ADC_ISQ */ -#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in regular sequence */ -#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in inserted sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ /* ADC_IDATAx x=0..3*/ -#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted data x */ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted data x */ /* ADC_RDATA */ -#define ADC_RDATA_RDATA BITS(0,15) /*!< regular data */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< routine data */ /* ADC_OVSAMPCTL */ -#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ -#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ -#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ -#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ /* ADC_SSTAT */ -#define ADC_SSTAT_WDE0 BIT(0) /*!< the mirror image of the WDE bit of ADC0 */ -#define ADC_SSTAT_EOC0 BIT(1) /*!< the mirror image of the EOC bit of ADC0 */ -#define ADC_SSTAT_EOIC0 BIT(2) /*!< the mirror image of the EOIC bit of ADC0 */ -#define ADC_SSTAT_STIC0 BIT(3) /*!< the mirror image of the STIC bit of ADC0 */ -#define ADC_SSTAT_STRC0 BIT(4) /*!< the mirror image of the STRC bit of ADC0 */ -#define ADC_SSTAT_ROVF0 BIT(5) /*!< the mirror image of the ROVF bit of ADC0 */ -#define ADC_SSTAT_WDE1 BIT(8) /*!< the mirror image of the WDE bit of ADC1 */ -#define ADC_SSTAT_EOC1 BIT(9) /*!< the mirror image of the EOC bit of ADC1 */ -#define ADC_SSTAT_EOIC1 BIT(10) /*!< the mirror image of the EOIC bit of ADC1 */ -#define ADC_SSTAT_STIC1 BIT(11) /*!< the mirror image of the STIC bit of ADC1 */ -#define ADC_SSTAT_STRC1 BIT(12) /*!< the mirror image of the STRC bit of ADC1 */ -#define ADC_SSTAT_ROVF1 BIT(13) /*!< the mirror image of the ROVF bit of ADC1 */ -#define ADC_SSTAT_WDE2 BIT(16) /*!< the mirror image of the WDE bit of ADC2 */ -#define ADC_SSTAT_EOC2 BIT(17) /*!< the mirror image of the EOC bit of ADC2 */ -#define ADC_SSTAT_EOIC2 BIT(18) /*!< the mirror image of the EOIC bit of ADC2 */ -#define ADC_SSTAT_STIC2 BIT(19) /*!< the mirror image of the STIC bit of ADC2 */ -#define ADC_SSTAT_STRC2 BIT(20) /*!< the mirror image of the STRC bit of ADC2 */ -#define ADC_SSTAT_ROVF2 BIT(21) /*!< the mirror image of the ROVF bit of ADC2 */ +#define ADC_SSTAT_WDE0 BIT(0) /*!< the mirror image of the WDE bit of ADC0 */ +#define ADC_SSTAT_EOC0 BIT(1) /*!< the mirror image of the EOC bit of ADC0 */ +#define ADC_SSTAT_EOIC0 BIT(2) /*!< the mirror image of the EOIC bit of ADC0 */ +#define ADC_SSTAT_STIC0 BIT(3) /*!< the mirror image of the STIC bit of ADC0 */ +#define ADC_SSTAT_STRC0 BIT(4) /*!< the mirror image of the STRC bit of ADC0 */ +#define ADC_SSTAT_ROVF0 BIT(5) /*!< the mirror image of the ROVF bit of ADC0 */ +#define ADC_SSTAT_WDE1 BIT(8) /*!< the mirror image of the WDE bit of ADC1 */ +#define ADC_SSTAT_EOC1 BIT(9) /*!< the mirror image of the EOC bit of ADC1 */ +#define ADC_SSTAT_EOIC1 BIT(10) /*!< the mirror image of the EOIC bit of ADC1 */ +#define ADC_SSTAT_STIC1 BIT(11) /*!< the mirror image of the STIC bit of ADC1 */ +#define ADC_SSTAT_STRC1 BIT(12) /*!< the mirror image of the STRC bit of ADC1 */ +#define ADC_SSTAT_ROVF1 BIT(13) /*!< the mirror image of the ROVF bit of ADC1 */ +#define ADC_SSTAT_WDE2 BIT(16) /*!< the mirror image of the WDE bit of ADC2 */ +#define ADC_SSTAT_EOC2 BIT(17) /*!< the mirror image of the EOC bit of ADC2 */ +#define ADC_SSTAT_EOIC2 BIT(18) /*!< the mirror image of the EOIC bit of ADC2 */ +#define ADC_SSTAT_STIC2 BIT(19) /*!< the mirror image of the STIC bit of ADC2 */ +#define ADC_SSTAT_STRC2 BIT(20) /*!< the mirror image of the STRC bit of ADC2 */ +#define ADC_SSTAT_ROVF2 BIT(21) /*!< the mirror image of the ROVF bit of ADC2 */ /* ADC_SYNCCTL */ -#define ADC_SYNCCTL_SYNCM BITS(0,4) /*!< ADC synchronization mode */ -#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC synchronization delay */ -#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC synchronization DMA disable mode */ -#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC synchronization DMA mode selection */ -#define ADC_SYNCCTL_ADCCK BITS(16,18) /*!< ADC clock */ -#define ADC_SYNCCTL_VBATEN BIT(22) /*!< channel 18 (1/4 voltate of external battery) enable of ADC0 */ -#define ADC_SYNCCTL_TSVREN BIT(23) /*!< channel 16 (temperature sensor) and 17 (internal reference voltage) enable of ADC0 */ +#define ADC_SYNCCTL_SYNCM BITS(0,4) /*!< ADC synchronization mode */ +#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC synchronization delay */ +#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC synchronization DMA disable mode */ +#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC synchronization DMA mode selection */ +#define ADC_SYNCCTL_ADCCK BITS(16,18) /*!< ADC clock */ +#define ADC_SYNCCTL_VBATEN BIT(22) /*!< channel 18 (1/4 voltate of external battery) enable of ADC0 */ +#define ADC_SYNCCTL_TSVREN BIT(23) /*!< channel 16 (temperature sensor) and 17 (internal reference voltage) enable of ADC0 */ /* ADC_SYNCDATA */ -#define ADC_SYNCDATA_SYNCDATA0 BITS(0,15) /*!< regular data1 in ADC synchronization mode */ -#define ADC_SYNCDATA_SYNCDATA1 BITS(16,31) /*!< regular data2 in ADC synchronization mode */ +#define ADC_SYNCDATA_SYNCDATA0 BITS(0,15) /*!< routine data1 in ADC synchronization mode */ +#define ADC_SYNCDATA_SYNCDATA1 BITS(16,31) /*!< routine data2 in ADC synchronization mode */ /* constants definitions */ /* ADC status flag */ -#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ -#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ -#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ -#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ -#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ -#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< regular data register overflow */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< routine channel start flag */ +#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */ /* adc_ctl0 register value */ #define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */ /* ADC special function definitions */ -#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ -#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ -#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted sequence convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ /* temperature sensor channel, internal reference voltage channel, VBAT channel */ #define ADC_VBAT_CHANNEL_SWITCH ADC_SYNCCTL_VBATEN /*!< VBAT channel */ #define ADC_TEMP_VREF_CHANNEL_SWITCH ADC_SYNCCTL_TSVREN /*!< Vref and Vtemp channel */ /* ADC synchronization mode */ -#define SYNCCTL_SYNCM(regval) (BITS(0,4) & ((uint32_t)(regval))) /*!< write value to ADC_CTL0_SYNCM bit field */ -#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */ -#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel & inserted parallel mode. ADC2 works independently */ -#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel & trigger rotation mode. ADC2 works independently */ -#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode. ADC2 works independently */ -#define ADC_DAUL_REGULAL_PARALLEL SYNCCTL_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode. ADC2 works independently */ -#define ADC_DAUL_REGULAL_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up mode. ADC2 works independently */ -#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode. ADC2 works independently */ -#define ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(17) /*!< all ADCs work in combined regular parallel & inserted parallel mode */ -#define ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(18) /*!< all ADCs work in combined regular parallel & trigger rotation mode */ +#define SYNCCTL_SYNCM(regval) (BITS(0,4) & ((uint32_t)(regval))) /*!< write value to ADC_CTL0_SYNCM bit field */ +#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */ +#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< ADC0 and ADC1 work in combined routine parallel & inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< ADC0 and ADC1 work in combined routine parallel & trigger rotation mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_PARALLEL SYNCCTL_SYNCM(6) /*!< ADC0 and ADC1 work in routine parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode. ADC2 works independently */ +#define ADC_ALL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(17) /*!< all ADCs work in combined routine parallel & inserted parallel mode */ +#define ADC_ALL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(18) /*!< all ADCs work in combined routine parallel & trigger rotation mode */ #define ADC_ALL_INSERTED_PARALLEL SYNCCTL_SYNCM(21) /*!< all ADCs work in inserted parallel mode */ -#define ADC_ALL_REGULAL_PARALLEL SYNCCTL_SYNCM(22) /*!< all ADCs work in regular parallel mode */ -#define ADC_ALL_REGULAL_FOLLOW_UP SYNCCTL_SYNCM(23) /*!< all ADCs work in follow-up mode */ +#define ADC_ALL_ROUTINE_PARALLEL SYNCCTL_SYNCM(22) /*!< all ADCs work in routine parallel mode */ +#define ADC_ALL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(23) /*!< all ADCs work in follow-up mode */ #define ADC_ALL_INSERTED_TRRIGGER_ROTATION SYNCCTL_SYNCM(25) /*!< all ADCs work in trigger rotation mode */ /* ADC data alignment */ -#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ -#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ -/* external trigger mode for regular and inserted channel */ -#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ -#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ -#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ -#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ +/* external trigger mode for routine and inserted channel */ +#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ +#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ +#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ +#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ -/* ADC external trigger select for regular channel */ +/* ADC external trigger select for routine channel */ #define CTL1_ETSRC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) -#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */ -#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */ -#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */ -#define ADC_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */ -#define ADC_EXTTRIG_REGULAR_T1_CH2 CTL1_ETSRC(4) /*!< timer 1 CC2 event select */ -#define ADC_EXTTRIG_REGULAR_T1_CH3 CTL1_ETSRC(5) /*!< timer 1 CC3 event select */ -#define ADC_EXTTRIG_REGULAR_T1_TRGO CTL1_ETSRC(6) /*!< timer 1 TRGO event select */ -#define ADC_EXTTRIG_REGULAR_T2_CH0 CTL1_ETSRC(7) /*!< timer 2 CC0 event select */ -#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(8) /*!< timer 2 TRGO event select */ -#define ADC_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(9) /*!< timer 3 CC3 event select */ -#define ADC_EXTTRIG_REGULAR_T4_CH0 CTL1_ETSRC(10) /*!< timer 4 CC0 event select */ -#define ADC_EXTTRIG_REGULAR_T4_CH1 CTL1_ETSRC(11) /*!< timer 4 CC1 event select */ -#define ADC_EXTTRIG_REGULAR_T4_CH2 CTL1_ETSRC(12) /*!< timer 4 CC2 event select */ -#define ADC_EXTTRIG_REGULAR_T7_CH0 CTL1_ETSRC(13) /*!< timer 7 CC0 event select */ -#define ADC_EXTTRIG_REGULAR_T7_TRGO CTL1_ETSRC(14) /*!< timer 7 TRGO event select */ -#define ADC_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(15) /*!< extiline 11 select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH2 CTL1_ETSRC(4) /*!< timer 1 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH3 CTL1_ETSRC(5) /*!< timer 1 CC3 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_TRGO CTL1_ETSRC(6) /*!< timer 1 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_T2_CH0 CTL1_ETSRC(7) /*!< timer 2 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T2_TRGO CTL1_ETSRC(8) /*!< timer 2 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_T3_CH3 CTL1_ETSRC(9) /*!< timer 3 CC3 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH0 CTL1_ETSRC(10) /*!< timer 4 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH1 CTL1_ETSRC(11) /*!< timer 4 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH2 CTL1_ETSRC(12) /*!< timer 4 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T7_CH0 CTL1_ETSRC(13) /*!< timer 7 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T7_TRGO CTL1_ETSRC(14) /*!< timer 7 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_EXTI_11 CTL1_ETSRC(15) /*!< extiline 11 select */ /* ADC external trigger select for inserted channel */ #define CTL1_ETSIC(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) -#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(0) /*!< timer0 capture compare 3 */ -#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(1) /*!< timer0 TRGO event */ -#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(2) /*!< timer1 capture compare 0 */ -#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(3) /*!< timer1 TRGO event */ -#define ADC_EXTTRIG_INSERTED_T2_CH1 CTL1_ETSIC(4) /*!< timer2 capture compare 1 */ -#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(5) /*!< timer2 capture compare 3 */ -#define ADC_EXTTRIG_INSERTED_T3_CH0 CTL1_ETSIC(6) /*!< timer3 capture compare 0 */ -#define ADC_EXTTRIG_INSERTED_T3_CH1 CTL1_ETSIC(7) /*!< timer3 capture compare 1 */ -#define ADC_EXTTRIG_INSERTED_T3_CH2 CTL1_ETSIC(8) /*!< timer3 capture compare 2 */ -#define ADC_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(9) /*!< timer3 capture compare TRGO */ -#define ADC_EXTTRIG_INSERTED_T4_CH3 CTL1_ETSIC(10) /*!< timer4 capture compare 3 */ -#define ADC_EXTTRIG_INSERTED_T4_TRGO CTL1_ETSIC(11) /*!< timer4 capture compare TRGO */ -#define ADC_EXTTRIG_INSERTED_T7_CH1 CTL1_ETSIC(12) /*!< timer7 capture compare 1 */ -#define ADC_EXTTRIG_INSERTED_T7_CH2 CTL1_ETSIC(13) /*!< timer7 capture compare 2 */ -#define ADC_EXTTRIG_INSERTED_T7_CH3 CTL1_ETSIC(14) /*!< timer7 capture compare 3 */ -#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(15) /*!< external interrupt line 15 */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(0) /*!< timer0 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(1) /*!< timer0 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(2) /*!< timer1 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(3) /*!< timer1 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T2_CH1 CTL1_ETSIC(4) /*!< timer2 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(5) /*!< timer2 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T3_CH0 CTL1_ETSIC(6) /*!< timer3 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T3_CH1 CTL1_ETSIC(7) /*!< timer3 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T3_CH2 CTL1_ETSIC(8) /*!< timer3 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(9) /*!< timer3 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T4_CH3 CTL1_ETSIC(10) /*!< timer4 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T4_TRGO CTL1_ETSIC(11) /*!< timer4 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T7_CH1 CTL1_ETSIC(12) /*!< timer7 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T7_CH2 CTL1_ETSIC(13) /*!< timer7 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T7_CH3 CTL1_ETSIC(14) /*!< timer7 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(15) /*!< external interrupt line 15 */ /* ADC channel sample time */ -#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */ -#define ADC_SAMPLETIME_3 SAMPTX_SPT(0) /*!< 3 sampling cycles */ -#define ADC_SAMPLETIME_15 SAMPTX_SPT(1) /*!< 15 sampling cycles */ -#define ADC_SAMPLETIME_28 SAMPTX_SPT(2) /*!< 28 sampling cycles */ -#define ADC_SAMPLETIME_56 SAMPTX_SPT(3) /*!< 56 sampling cycles */ -#define ADC_SAMPLETIME_84 SAMPTX_SPT(4) /*!< 84 sampling cycles */ -#define ADC_SAMPLETIME_112 SAMPTX_SPT(5) /*!< 112 sampling cycles */ -#define ADC_SAMPLETIME_144 SAMPTX_SPT(6) /*!< 144 sampling cycles */ -#define ADC_SAMPLETIME_480 SAMPTX_SPT(7) /*!< 480 sampling cycles */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */ +#define ADC_SAMPLETIME_3 SAMPTX_SPT(0) /*!< 3 sampling cycles */ +#define ADC_SAMPLETIME_15 SAMPTX_SPT(1) /*!< 15 sampling cycles */ +#define ADC_SAMPLETIME_28 SAMPTX_SPT(2) /*!< 28 sampling cycles */ +#define ADC_SAMPLETIME_56 SAMPTX_SPT(3) /*!< 56 sampling cycles */ +#define ADC_SAMPLETIME_84 SAMPTX_SPT(4) /*!< 84 sampling cycles */ +#define ADC_SAMPLETIME_112 SAMPTX_SPT(5) /*!< 112 sampling cycles */ +#define ADC_SAMPLETIME_144 SAMPTX_SPT(6) /*!< 144 sampling cycles */ +#define ADC_SAMPLETIME_480 SAMPTX_SPT(7) /*!< 480 sampling cycles */ /* adc_ioffx register value */ -#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */ /* adc_wdht register value */ -#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */ +#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */ /* adc_wdlt register value */ -#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */ +#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */ /* adc_rsqx register value */ -#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */ /* adc_isq register value */ -#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */ +#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */ /* adc_ovsampctl register value */ /* ADC resolution */ -#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) /*!< write value to ADC_CTL0_DRES bit field */ -#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ -#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ -#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ -#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ +#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) /*!< write value to ADC_CTL0_DRES bit field */ +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ /* oversampling shift */ -#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ -#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ -#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ /* oversampling ratio */ -#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ -#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ -#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ -#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ -#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ -#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ -#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ -#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ -#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ - -/* triggered Oversampling */ -#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ -#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ - -/* ADC channel group definitions */ -#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */ -#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted channel group */ -#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ -#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC channel sequence definitions */ +#define ADC_ROUTINE_CHANNEL ((uint8_t)0x01U) /*!< adc routine sequence */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted sequence */ +#define ADC_ROUTINE_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both routine and inserted sequence */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of routine & inserted sequence */ /* ADC inserted channel definitions */ -#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */ -#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */ -#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */ -#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */ /* ADC channel definitions */ -#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ -#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ -#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ -#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ -#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ -#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ -#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ -#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ -#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ -#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ -#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ -#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ -#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ -#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ -#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ -#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ -#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ -#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ -#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ +#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */ /* ADC interrupt flag */ -#define ADC_INT_WDE ADC_CTL0_WDEIE /*!< analog watchdog event interrupt */ -#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< end of group conversion interrupt */ -#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< end of inserted group conversion interrupt */ -#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< regular data register overflow */ +#define ADC_INT_WDE ADC_CTL0_WDEIE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< end of sequence conversion interrupt */ +#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< end of inserted sequence conversion interrupt */ +#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< routine data register overflow */ /* ADC interrupt flag */ -#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ -#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ -#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ -#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< regular data register overflow */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion interrupt */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion interrupt */ +#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */ /* configure the ADC clock for all the ADCs */ #define SYNCCTL_ADCCK(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) -#define ADC_ADCCK_PCLK2_DIV2 SYNCCTL_ADCCK(0) /*!< PCLK2 div2 */ -#define ADC_ADCCK_PCLK2_DIV4 SYNCCTL_ADCCK(1) /*!< PCLK2 div4 */ -#define ADC_ADCCK_PCLK2_DIV6 SYNCCTL_ADCCK(2) /*!< PCLK2 div6 */ -#define ADC_ADCCK_PCLK2_DIV8 SYNCCTL_ADCCK(3) /*!< PCLK2 div8 */ -#define ADC_ADCCK_HCLK_DIV5 SYNCCTL_ADCCK(4) /*!< HCLK div5 */ -#define ADC_ADCCK_HCLK_DIV6 SYNCCTL_ADCCK(5) /*!< HCLK div6 */ -#define ADC_ADCCK_HCLK_DIV10 SYNCCTL_ADCCK(6) /*!< HCLK div10 */ -#define ADC_ADCCK_HCLK_DIV20 SYNCCTL_ADCCK(7) /*!< HCLK div20 */ +#define ADC_ADCCK_PCLK2_DIV2 SYNCCTL_ADCCK(0) /*!< PCLK2 div2 */ +#define ADC_ADCCK_PCLK2_DIV4 SYNCCTL_ADCCK(1) /*!< PCLK2 div4 */ +#define ADC_ADCCK_PCLK2_DIV6 SYNCCTL_ADCCK(2) /*!< PCLK2 div6 */ +#define ADC_ADCCK_PCLK2_DIV8 SYNCCTL_ADCCK(3) /*!< PCLK2 div8 */ +#define ADC_ADCCK_HCLK_DIV5 SYNCCTL_ADCCK(4) /*!< HCLK div5 */ +#define ADC_ADCCK_HCLK_DIV6 SYNCCTL_ADCCK(5) /*!< HCLK div6 */ +#define ADC_ADCCK_HCLK_DIV10 SYNCCTL_ADCCK(6) /*!< HCLK div10 */ +#define ADC_ADCCK_HCLK_DIV20 SYNCCTL_ADCCK(7) /*!< HCLK div20 */ /* ADC synchronization delay */ -#define ADC_SYNC_DELAY_5CYCLE ((uint32_t)0x00000000U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ -#define ADC_SYNC_DELAY_6CYCLE ((uint32_t)0x00000100U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ -#define ADC_SYNC_DELAY_7CYCLE ((uint32_t)0x00000200U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ -#define ADC_SYNC_DELAY_8CYCLE ((uint32_t)0x00000300U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ -#define ADC_SYNC_DELAY_9CYCLE ((uint32_t)0x00000400U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ -#define ADC_SYNC_DELAY_10CYCLE ((uint32_t)0x00000500U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ -#define ADC_SYNC_DELAY_11CYCLE ((uint32_t)0x00000600U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ -#define ADC_SYNC_DELAY_12CYCLE ((uint32_t)0x00000700U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ -#define ADC_SYNC_DELAY_13CYCLE ((uint32_t)0x00000800U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ -#define ADC_SYNC_DELAY_14CYCLE ((uint32_t)0x00000900U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ -#define ADC_SYNC_DELAY_15CYCLE ((uint32_t)0x00000A00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ -#define ADC_SYNC_DELAY_16CYCLE ((uint32_t)0x00000B00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ -#define ADC_SYNC_DELAY_17CYCLE ((uint32_t)0x00000C00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ -#define ADC_SYNC_DELAY_18CYCLE ((uint32_t)0x00000D00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ -#define ADC_SYNC_DELAY_19CYCLE ((uint32_t)0x00000E00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ -#define ADC_SYNC_DELAY_20CYCLE ((uint32_t)0x00000F00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ +#define ADC_SYNC_DELAY_5CYCLE ((uint32_t)0x00000000U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ +#define ADC_SYNC_DELAY_6CYCLE ((uint32_t)0x00000100U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ +#define ADC_SYNC_DELAY_7CYCLE ((uint32_t)0x00000200U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ +#define ADC_SYNC_DELAY_8CYCLE ((uint32_t)0x00000300U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ +#define ADC_SYNC_DELAY_9CYCLE ((uint32_t)0x00000400U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ +#define ADC_SYNC_DELAY_10CYCLE ((uint32_t)0x00000500U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ +#define ADC_SYNC_DELAY_11CYCLE ((uint32_t)0x00000600U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ +#define ADC_SYNC_DELAY_12CYCLE ((uint32_t)0x00000700U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ +#define ADC_SYNC_DELAY_13CYCLE ((uint32_t)0x00000800U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ +#define ADC_SYNC_DELAY_14CYCLE ((uint32_t)0x00000900U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ +#define ADC_SYNC_DELAY_15CYCLE ((uint32_t)0x00000A00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ +#define ADC_SYNC_DELAY_16CYCLE ((uint32_t)0x00000B00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ +#define ADC_SYNC_DELAY_17CYCLE ((uint32_t)0x00000C00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ +#define ADC_SYNC_DELAY_18CYCLE ((uint32_t)0x00000D00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ +#define ADC_SYNC_DELAY_19CYCLE ((uint32_t)0x00000E00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ +#define ADC_SYNC_DELAY_20CYCLE ((uint32_t)0x00000F00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ /* ADC synchronization DMA mode selection */ -#define ADC_SYNC_DMA_DISABLE ((uint32_t)0x00000000U) /*!< ADC synchronization DMA disabled */ -#define ADC_SYNC_DMA_MODE0 ((uint32_t)0x00004000U) /*!< ADC synchronization DMA mode 0 */ -#define ADC_SYNC_DMA_MODE1 ((uint32_t)0x00008000U) /*!< ADC synchronization DMA mode 1 */ +#define ADC_SYNC_DMA_DISABLE ((uint32_t)0x00000000U) /*!< ADC synchronization DMA disabled */ +#define ADC_SYNC_DMA_MODE0 ((uint32_t)0x00004000U) /*!< ADC synchronization DMA mode 0 */ +#define ADC_SYNC_DMA_MODE1 ((uint32_t)0x00008000U) /*!< ADC synchronization DMA mode 1 */ /* end of conversion mode */ -#define ADC_EOC_SET_SEQUENCE ((uint8_t)0x00U) /*!< only at the end of a sequence of regular conversions, the EOC bit is set */ -#define ADC_EOC_SET_CONVERSION ((uint8_t)0x01U) /*!< at the end of each regular conversion, the EOC bit is set */ +#define ADC_EOC_SET_SEQUENCE ((uint8_t)0x00U) /*!< only at the end of a sequence of routine conversions, the EOC bit is set */ +#define ADC_EOC_SET_CONVERSION ((uint8_t)0x01U) /*!< at the end of each routine conversion, the EOC bit is set */ /* function declarations */ /* initialization config */ @@ -437,35 +435,35 @@ void adc_oversample_mode_disable(uint32_t adc_periph); void adc_dma_mode_enable(uint32_t adc_periph); /* disable DMA request */ void adc_dma_mode_disable(uint32_t adc_periph); -/* when DMA=1, the DMA engine issues a request at end of each regular conversion */ +/* when DMA=1, the DMA engine issues a request at end of each routine conversion */ void adc_dma_request_after_last_enable(uint32_t adc_periph); /* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */ void adc_dma_request_after_last_disable(uint32_t adc_periph); -/* regular group and inserted group config */ +/* routine sequence and inserted sequence config */ /* configure ADC discontinuous mode */ -void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length); -/* configure the length of regular channel group or inserted channel group */ -void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length); -/* configure ADC regular channel */ -void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_sequence , uint8_t length); +/* configure the length of routine sequence or inserted sequence */ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t length); +/* configure ADC routine channel */ +void adc_routine_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); /* configure ADC inserted channel */ void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); /* configure ADC inserted channel offset */ void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset); /* configure ADC external trigger source */ -void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source); +void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t external_trigger_source); /* enable ADC external trigger */ -void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode); +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t trigger_mode); /* enable ADC software trigger */ -void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group); +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_sequence); /* configure end of conversion mode */ void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection); /* get channel data */ -/* read ADC regular group data register */ -uint16_t adc_regular_data_read(uint32_t adc_periph); -/* read ADC inserted group data register */ +/* read ADC routine data register */ +uint16_t adc_routine_data_read(uint32_t adc_periph); +/* read ADC inserted data register */ uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel); /* watchdog config */ @@ -473,10 +471,10 @@ uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel); void adc_watchdog_single_channel_disable(uint32_t adc_periph ); /* enable ADC analog watchdog single channel */ void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel); -/* configure ADC analog watchdog group channel */ -void adc_watchdog_group_channel_enable(uint32_t adc_periph , uint8_t adc_channel_group); +/* configure ADC analog watchdog sequence */ +void adc_watchdog_sequence_channel_enable(uint32_t adc_periph , uint8_t adc_sequence); /* disable ADC analog watchdog */ -void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group); +void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_sequence); /* configure ADC analog watchdog threshold */ void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold); @@ -486,7 +484,7 @@ FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag); /* clear the ADC flag bits */ void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag); /* get the bit state of ADCx software start conversion */ -FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph); +FlagStatus adc_routine_software_startconv_flag_get(uint32_t adc_periph); /* get the bit state of ADCx software inserted channel start conversion */ FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph); /* get the ADC interrupt bits */ @@ -509,7 +507,7 @@ void adc_sync_dma_config(uint32_t dma_mode ); void adc_sync_dma_request_after_last_enable(void); /* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */ void adc_sync_dma_request_after_last_disable(void); -/* read ADC sync regular data register */ -uint32_t adc_sync_regular_data_read(void); +/* read ADC sync routine data register */ +uint32_t adc_sync_routine_data_read(void); #endif /* GD32F4XX_ADC_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h index ac96a3c..a9fbc5f 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h @@ -2,36 +2,33 @@ \file gd32f4xx_can.h \brief definitions for the CAN - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2019-11-27, V2.0.1, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -42,99 +39,99 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* CAN definitions */ -#define CAN0 CAN_BASE /*!< CAN0 base address */ -#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ /* registers definitions */ -#define CAN_CTL(canx) REG32((canx) + 0x00U) /*!< CAN control register */ -#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ -#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ -#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ -#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ -#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ -#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ -#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ -#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ -#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ -#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ -#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ -#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ -#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ -#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ -#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ -#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ -#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ -#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ -#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ -#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ -#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ -#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ -#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1BCU) /*!< CAN receive FIFO0 mailbox data1 register */ -#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */ -#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */ -#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */ -#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */ -#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */ -#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */ -#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */ -#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */ -#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */ -#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */ -#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */ -#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */ -#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */ -#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */ -#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */ -#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */ -#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */ -#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */ -#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */ -#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */ -#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */ -#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */ -#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */ -#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */ -#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */ -#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */ -#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */ -#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */ -#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */ -#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */ -#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */ -#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */ -#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */ -#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */ -#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */ -#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */ -#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */ -#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */ -#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */ -#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */ -#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */ -#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */ -#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */ -#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */ -#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */ -#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */ -#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */ -#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */ -#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */ -#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */ -#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */ -#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */ -#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */ -#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */ -#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */ -#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */ -#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */ -#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */ -#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */ -#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */ -#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */ -#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */ -#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */ -#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */ -#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< CAN filter 27 data 1 register */ +#define CAN_CTL(canx) REG32((canx) + 0x00000000U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x00000004U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x00000008U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0000000CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x00000010U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x00000014U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x00000018U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x0000001CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x00000180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x00000184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x00000188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x0000018CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x00000190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x00000194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x00000198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x0000019CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x000001A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x000001A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x000001A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x000001ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x000001B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x000001B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x000001B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x000001BCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x000001C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x000001C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x000001C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x000001CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x00000200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x00000204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x0000020CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x00000214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x0000021CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x00000240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x00000248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x00000250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x00000258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x00000260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x00000268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x00000270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x00000278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x00000280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x00000288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x00000290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x00000298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x000002A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x000002A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x000002B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x000002B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x000002C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x000002C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x000002D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x000002D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x000002E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x000002E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x000002F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x000003F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x00000300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x00000308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x00000310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x00000318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x00000244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x0000024CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x00000254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x0000025CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x00000264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x0000026CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x00000274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x0000027CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x00000284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x0000028CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x00000294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x0000029CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x000002A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x000002ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x000002B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x000002BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x000002C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x0000024CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x000002D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x000002DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x000002E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x000002ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x000002F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x000002FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x00000304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x0000030CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x00000314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x0000031CU) /*!< CAN filter 27 data 1 register */ /* CAN transmit mailbox bank */ #define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank) * 0x10U)) /*!< CAN transmit mailbox identifier register */ @@ -146,7 +143,7 @@ OF SUCH DAMAGE. #define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */ #define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */ -/* CAN receive fifo mailbox bank */ +/* CAN receive FIFO mailbox bank */ #define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox identifier register */ #define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox property register */ #define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data0 register */ @@ -296,10 +293,10 @@ OF SUCH DAMAGE. #define CAN_FCTL_HBC1F BITS(8,13) /*!< header bank of CAN1 filter */ /* CAN_FMCFG */ -#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask*/ +#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask */ /* CAN_FSCFG */ -#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits*/ +#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits */ /* CAN_FAFIFO */ #define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */ @@ -310,7 +307,7 @@ OF SUCH DAMAGE. /* CAN_FxDATAy */ #define CAN_FDATA_FD(regval) BIT(regval) /*!< filter data */ -/* consts definitions */ +/* constants definitions */ /* define the CAN bit position and its register index offset */ #define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) #define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6))) @@ -329,56 +326,54 @@ OF SUCH DAMAGE. #define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */ /* CAN flags */ -typedef enum -{ +typedef enum { /* flags in STAT register */ - CAN_FLAG_RXL = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< RX level */ - CAN_FLAG_LASTRX = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< last sample value of RX pin */ - CAN_FLAG_RS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< receiving state */ - CAN_FLAG_TS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< transmitting state */ - CAN_FLAG_SLPIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< status change flag of entering sleep working mode */ - CAN_FLAG_WUIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< status change flag of wakeup from sleep working mode */ - CAN_FLAG_ERRIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< error flag */ - CAN_FLAG_SLPWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< sleep working state */ - CAN_FLAG_IWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< initial working state */ + CAN_FLAG_RXL = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< RX level */ + CAN_FLAG_LASTRX = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< last sample value of RX pin */ + CAN_FLAG_RS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< receiving state */ + CAN_FLAG_TS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< transmitting state */ + CAN_FLAG_SLPIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< status change flag of entering sleep working mode */ + CAN_FLAG_WUIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< status change flag of wakeup from sleep working mode */ + CAN_FLAG_ERRIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< error flag */ + CAN_FLAG_SLPWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< sleep working state */ + CAN_FLAG_IWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< initial working state */ /* flags in TSTAT register */ - CAN_FLAG_TMLS2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 31U), /*!< transmit mailbox 2 last sending in Tx FIFO */ - CAN_FLAG_TMLS1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 30U), /*!< transmit mailbox 1 last sending in Tx FIFO */ - CAN_FLAG_TMLS0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 29U), /*!< transmit mailbox 0 last sending in Tx FIFO */ - CAN_FLAG_TME2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 28U), /*!< transmit mailbox 2 empty */ - CAN_FLAG_TME1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 27U), /*!< transmit mailbox 1 empty */ - CAN_FLAG_TME0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 26U), /*!< transmit mailbox 0 empty */ - CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ - CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ - CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ - CAN_FLAG_MAL2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 18U), /*!< mailbox 2 arbitration lost */ - CAN_FLAG_MAL1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 10U), /*!< mailbox 1 arbitration lost */ - CAN_FLAG_MAL0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 2U), /*!< mailbox 0 arbitration lost */ - CAN_FLAG_MTFNERR2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 17U), /*!< mailbox 2 transmit finished with no error */ - CAN_FLAG_MTFNERR1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 9U), /*!< mailbox 1 transmit finished with no error */ - CAN_FLAG_MTFNERR0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 1U), /*!< mailbox 0 transmit finished with no error */ - CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ - CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ - CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ + CAN_FLAG_TMLS2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 31U), /*!< transmit mailbox 2 last sending in TX FIFO */ + CAN_FLAG_TMLS1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 30U), /*!< transmit mailbox 1 last sending in TX FIFO */ + CAN_FLAG_TMLS0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 29U), /*!< transmit mailbox 0 last sending in TX FIFO */ + CAN_FLAG_TME2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 28U), /*!< transmit mailbox 2 empty */ + CAN_FLAG_TME1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 27U), /*!< transmit mailbox 1 empty */ + CAN_FLAG_TME0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 26U), /*!< transmit mailbox 0 empty */ + CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ + CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ + CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ + CAN_FLAG_MAL2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 18U), /*!< mailbox 2 arbitration lost */ + CAN_FLAG_MAL1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 10U), /*!< mailbox 1 arbitration lost */ + CAN_FLAG_MAL0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 2U), /*!< mailbox 0 arbitration lost */ + CAN_FLAG_MTFNERR2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 17U), /*!< mailbox 2 transmit finished with no error */ + CAN_FLAG_MTFNERR1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 9U), /*!< mailbox 1 transmit finished with no error */ + CAN_FLAG_MTFNERR0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 1U), /*!< mailbox 0 transmit finished with no error */ + CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ + CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ + CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ /* flags in RFIFO0 register */ - CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ - CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ + CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ + CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ /* flags in RFIFO1 register */ - CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ - CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ + CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ + CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ /* flags in ERR register */ - CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ - CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ - CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ -}can_flag_enum; + CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ + CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ + CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ +} can_flag_enum; /* CAN interrupt flags */ -typedef enum -{ +typedef enum { /* interrupt flags in STAT register */ - CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ - CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ - CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ + CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ /* interrupt flags in TSTAT register */ CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */ CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */ @@ -390,44 +385,41 @@ typedef enum /* interrupt flags in RFIFO0 register */ CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */ CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */ - CAN_INT_FLAG_RFL1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 2U, 4U), /*!< receive FIFO0 not empty interrupt flag */ + CAN_INT_FLAG_RFL1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 2U, 4U), /*!< receive FIFO1 not empty interrupt flag */ /* interrupt flags in ERR register */ - CAN_INT_FLAG_ERRN = CAN_REGIDX_BITS(ERR_REG_OFFSET, 3U, 11U), /*!< error number interrupt flag */ - CAN_INT_FLAG_BOERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 2U, 10U), /*!< bus-off error interrupt flag */ - CAN_INT_FLAG_PERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 1U, 9U), /*!< passive error interrupt flag */ - CAN_INT_FLAG_WERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 0U, 8U), /*!< warning error interrupt flag */ -}can_interrupt_flag_enum; - -/* CAN initiliaze parameters struct */ -typedef struct -{ - uint8_t working_mode; /*!< CAN working mode */ + CAN_INT_FLAG_ERRN = CAN_REGIDX_BITS(ERR_REG_OFFSET, 3U, 11U), /*!< error number interrupt flag */ + CAN_INT_FLAG_BOERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 2U, 10U), /*!< bus-off error interrupt flag */ + CAN_INT_FLAG_PERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 1U, 9U), /*!< passive error interrupt flag */ + CAN_INT_FLAG_WERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 0U, 8U), /*!< warning error interrupt flag */ +} can_interrupt_flag_enum; + +/* CAN initiliaze parameters structure */ +typedef struct { + uint8_t working_mode; /*!< CAN working mode */ uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ uint8_t time_segment_1; /*!< time segment 1 */ uint8_t time_segment_2; /*!< time segment 2 */ ControlStatus time_triggered; /*!< time triggered communication mode */ ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ ControlStatus auto_wake_up; /*!< automatic wake-up mode */ - ControlStatus no_auto_retrans; /*!< automatic retransmission mode disable */ + ControlStatus auto_retrans; /*!< automatic retransmission mode */ ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */ ControlStatus trans_fifo_order; /*!< transmit FIFO order */ uint16_t prescaler; /*!< baudrate prescaler */ -}can_parameter_struct; +} can_parameter_struct; -/* CAN transmit message struct */ -typedef struct -{ +/* CAN transmit message structure */ +typedef struct { uint32_t tx_sfid; /*!< standard format frame identifier */ uint32_t tx_efid; /*!< extended format frame identifier */ uint8_t tx_ff; /*!< format of frame, standard or extended format */ uint8_t tx_ft; /*!< type of frame, data or remote */ uint8_t tx_dlen; /*!< data length */ uint8_t tx_data[8]; /*!< transmit data */ -}can_trasnmit_message_struct; +} can_trasnmit_message_struct; -/* CAN receive message struct */ -typedef struct -{ +/* CAN receive message structure */ +typedef struct { uint32_t rx_sfid; /*!< standard format frame identifier */ uint32_t rx_efid; /*!< extended format frame identifier */ uint8_t rx_ff; /*!< format of frame, standard or extended format */ @@ -437,10 +429,9 @@ typedef struct uint8_t rx_fi; /*!< filtering index */ } can_receive_message_struct; -/* CAN filter parameters struct */ -typedef struct -{ - uint16_t filter_list_high; /*!< filter list number high bits*/ +/* CAN filter parameters structure */ +typedef struct { + uint16_t filter_list_high; /*!< filter list number high bits */ uint16_t filter_list_low; /*!< filter list number low bits */ uint16_t filter_mask_high; /*!< filter mask number high bits */ uint16_t filter_mask_low; /*!< filter mask number low bits */ @@ -449,11 +440,10 @@ typedef struct uint16_t filter_mode; /*!< filter mode, list or mask */ uint16_t filter_bits; /*!< filter scale */ ControlStatus filter_enable; /*!< filter work or not */ -}can_filter_parameter_struct; +} can_filter_parameter_struct; /* CAN errors */ -typedef enum -{ +typedef enum { CAN_ERROR_NONE = 0, /*!< no error */ CAN_ERROR_FILL, /*!< fill error */ CAN_ERROR_FORMATE, /*!< format error */ @@ -462,38 +452,36 @@ typedef enum CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */ CAN_ERROR_CRC, /*!< CRC error */ CAN_ERROR_SOFTWARECFG, /*!< software configure */ -}can_error_enum; +} can_error_enum; /* transmit states */ -typedef enum -{ - CAN_TRANSMIT_FAILED = 0U, /*!< CAN transmitted failure */ - CAN_TRANSMIT_OK = 1U, /*!< CAN transmitted success */ - CAN_TRANSMIT_PENDING = 2U, /*!< CAN transmitted pending */ - CAN_TRANSMIT_NOMAILBOX = 4U, /*!< no empty mailbox to be used for CAN */ -}can_transmit_state_enum; - -typedef enum -{ +typedef enum { + CAN_TRANSMIT_FAILED = 0U, /*!< CAN transmitted failure */ + CAN_TRANSMIT_OK = 1U, /*!< CAN transmitted success */ + CAN_TRANSMIT_PENDING = 2U, /*!< CAN transmitted pending */ + CAN_TRANSMIT_NOMAILBOX = 4U, /*!< no empty mailbox to be used for CAN */ +} can_transmit_state_enum; + +typedef enum { CAN_INIT_STRUCT = 0, /* CAN initiliaze parameters struct */ CAN_FILTER_STRUCT, /* CAN filter parameters struct */ CAN_TX_MESSAGE_STRUCT, /* CAN transmit message struct */ CAN_RX_MESSAGE_STRUCT, /* CAN receive message struct */ -}can_struct_type_enum; +} can_struct_type_enum; -/* CAN baudrate prescaler*/ +/* CAN baudrate prescaler */ #define BT_BAUDPSC(regval) (BITS(0,9) & ((uint32_t)(regval) << 0)) -/* CAN bit segment 1*/ +/* CAN bit segment 1 */ #define BT_BS1(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) -/* CAN bit segment 2*/ +/* CAN bit segment 2 */ #define BT_BS2(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) -/* CAN resynchronization jump width*/ +/* CAN resynchronization jump width */ #define BT_SJW(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) -/* CAN communication mode*/ +/* CAN communication mode */ #define BT_MODE(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) /* CAN FDATA high 16 bits */ @@ -502,13 +490,13 @@ typedef enum /* CAN FDATA low 16 bits */ #define FDATA_MASK_LOW(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) -/* CAN1 filter start bank_number*/ +/* CAN1 filter start bank_number */ #define FCTL_HBC1F(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) -/* CAN transmit mailbox extended identifier*/ +/* CAN transmit mailbox extended identifier */ #define TMI_EFID(regval) (BITS(3,31) & ((uint32_t)(regval) << 3)) -/* CAN transmit mailbox standard identifier*/ +/* CAN transmit mailbox standard identifier */ #define TMI_SFID(regval) (BITS(21,31) & ((uint32_t)(regval) << 21)) /* transmit data byte 0 */ @@ -520,25 +508,25 @@ typedef enum /* transmit data byte 2 */ #define TMDATA0_DB2(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) -/* transmit data byte 3 */ +/* transmit data byte 3 */ #define TMDATA0_DB3(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) -/* transmit data byte 4 */ +/* transmit data byte 4 */ #define TMDATA1_DB4(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) -/* transmit data byte 5 */ +/* transmit data byte 5 */ #define TMDATA1_DB5(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) -/* transmit data byte 6 */ +/* transmit data byte 6 */ #define TMDATA1_DB6(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) -/* transmit data byte 7 */ +/* transmit data byte 7 */ #define TMDATA1_DB7(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) -/* receive mailbox extended identifier*/ +/* receive mailbox extended identifier */ #define GET_RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3U, 31U) -/* receive mailbox standrad identifier*/ +/* receive mailbox standard identifier */ #define GET_RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21U, 31U) /* receive data length */ @@ -571,25 +559,25 @@ typedef enum /* receive data byte 7 */ #define GET_RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24U, 31U) -/* error number */ +/* error number */ #define GET_ERR_ERRN(regval) GET_BITS((uint32_t)(regval), 4U, 6U) -/* transmit error count */ +/* transmit error count */ #define GET_ERR_TECNT(regval) GET_BITS((uint32_t)(regval), 16U, 23U) -/* receive error count */ +/* receive error count */ #define GET_ERR_RECNT(regval) GET_BITS((uint32_t)(regval), 24U, 31U) /* CAN errors */ #define ERR_ERRN(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) -#define CAN_ERRN_0 ERR_ERRN(0U) /* no error */ -#define CAN_ERRN_1 ERR_ERRN(1U) /*!< fill error */ -#define CAN_ERRN_2 ERR_ERRN(2U) /*!< format error */ -#define CAN_ERRN_3 ERR_ERRN(3U) /*!< ACK error */ -#define CAN_ERRN_4 ERR_ERRN(4U) /*!< bit recessive error */ -#define CAN_ERRN_5 ERR_ERRN(5U) /*!< bit dominant error */ -#define CAN_ERRN_6 ERR_ERRN(6U) /*!< CRC error */ -#define CAN_ERRN_7 ERR_ERRN(7U) /*!< software error */ +#define CAN_ERRN_0 ERR_ERRN(0U) /*!< no error */ +#define CAN_ERRN_1 ERR_ERRN(1U) /*!< fill error */ +#define CAN_ERRN_2 ERR_ERRN(2U) /*!< format error */ +#define CAN_ERRN_3 ERR_ERRN(3U) /*!< ACK error */ +#define CAN_ERRN_4 ERR_ERRN(4U) /*!< bit recessive error */ +#define CAN_ERRN_5 ERR_ERRN(5U) /*!< bit dominant error */ +#define CAN_ERRN_6 ERR_ERRN(6U) /*!< CRC error */ +#define CAN_ERRN_7 ERR_ERRN(7U) /*!< software error */ #define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */ @@ -643,11 +631,11 @@ typedef enum #define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */ #define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */ -/* CAN receive fifo */ +/* CAN receive FIFO */ #define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ #define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ -/* frame number of receive fifo */ +/* frame number of receive FIFO */ #define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */ #define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */ @@ -693,15 +681,18 @@ typedef enum #define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */ /* function declarations */ +/* initialization functions */ /* deinitialize CAN */ void can_deinit(uint32_t can_periph); -/* initialize CAN struct */ -void can_struct_para_init(can_struct_type_enum type, void* p_struct); +/* initialize CAN structure */ +void can_struct_para_init(can_struct_type_enum type, void *p_struct); /* initialize CAN */ -ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init); -/* CAN filter init */ -void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init); -/* set can1 fliter start bank number */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init); +/* CAN filter initialization */ +void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init); + +/* function configuration */ +/* set can1 filter start bank number */ void can1_filter_start_bank(uint8_t start_bank); /* enable functions */ /* CAN debug freeze enable */ @@ -715,14 +706,14 @@ void can_time_trigger_mode_disable(uint32_t can_periph); /* transmit functions */ /* transmit CAN message */ -uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message); +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message); /* get CAN transmit state */ can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number); /* stop CAN transmission */ void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); /* CAN receive message */ -void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message); -/* CAN release fifo */ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message); +/* CAN release FIFO */ void can_fifo_release(uint32_t can_periph, uint8_t fifo_number); /* CAN receive message length */ uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number); @@ -731,21 +722,22 @@ ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode); /* CAN wakeup from sleep mode */ ErrStatus can_wakeup(uint32_t can_periph); -/* CAN get error */ +/* CAN get error type */ can_error_enum can_error_get(uint32_t can_periph); /* get CAN receive error number */ uint8_t can_receive_error_number_get(uint32_t can_periph); /* get CAN transmit error number */ uint8_t can_transmit_error_number_get(uint32_t can_periph); -/* CAN interrupt enable */ -void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); -/* CAN interrupt disable */ -void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); +/* interrupt & flag functions */ /* CAN get flag state */ FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); /* CAN clear flag state */ void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN interrupt enable */ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); +/* CAN interrupt disable */ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); /* CAN get interrupt flag state */ FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag); /* CAN clear interrupt flag state */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h index e14df03..da5bad5 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h @@ -2,13 +2,11 @@ \file gd32f4xx_crc.h \brief definitions for the CRC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -40,12 +38,12 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* CRC definitions */ -#define CRC CRC_BASE +#define CRC CRC_BASE /*!< CRC base address */ /* registers definitions */ -#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ -#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ -#define CRC_CTL REG32(CRC + 0x08U) /*!< CRC control register */ +#define CRC_DATA REG32(CRC + 0x00000000U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x00000004U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x00000008U) /*!< CRC control register */ /* bits definitions */ /* CRC_DATA */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h index 2eafebb..e1179a2 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h @@ -2,13 +2,11 @@ \file gd32f4xx_ctc.h \brief definitions for the CTC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -64,7 +62,6 @@ OF SUCH DAMAGE. #define CTC_CTL1_CKLIM BITS(16,23) /*!< clock trim base limit value */ #define CTC_CTL1_REFPSC BITS(24,26) /*!< reference signal source prescaler */ #define CTC_CTL1_REFSEL BITS(28,29) /*!< reference signal source selection */ -#define CTC_CTL1_USBSOFSEL BIT(30) /*!< USBFS or USBHS SOF signal selection */ #define CTC_CTL1_REFPOL BIT(31) /*!< reference signal source polarity */ /* CTC_STAT */ @@ -93,15 +90,10 @@ OF SUCH DAMAGE. #define CTC_REFSOURCE_POLARITY_FALLING CTC_CTL1_REFPOL /*!< reference signal source polarity is falling edge*/ #define CTC_REFSOURCE_POLARITY_RISING ((uint32_t)0x00000000U) /*!< reference signal source polarity is rising edge*/ -/* USBFS or USBHS SOF signal selection definitions */ -#define CTC_USBSOFSEL_USBHS CTC_CTL1_USBSOFSEL /*!< USBHS SOF signal is selected*/ -#define CTC_USBSOFSEL_USBFS ((uint32_t)0x00000000U) /*!< USBFS SOF signal is selected*/ - /* reference signal source selection definitions */ #define CTL1_REFSEL(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) #define CTC_REFSOURCE_GPIO CTL1_REFSEL(0) /*!< GPIO is selected */ #define CTC_REFSOURCE_LXTAL CTL1_REFSEL(1) /*!< LXTAL is clock selected */ -#define CTC_REFSOURCE_USBSOF CTL1_REFSEL(2) /*!< USBSOF is selected */ /* reference signal source prescaler definitions */ #define CTL1_REFPSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) @@ -155,8 +147,6 @@ void ctc_hardware_trim_mode_config(uint32_t hardmode); /* configure reference signal source polarity */ void ctc_refsource_polarity_config(uint32_t polarity); -/* select USBFS or USBHS SOF signal */ -void ctc_usbsof_signal_select(uint32_t usbsof); /* select reference signal source */ void ctc_refsource_signal_select(uint32_t refs); /* configure reference signal source prescaler */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h index 482f2bb..2f18508 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h @@ -2,13 +2,11 @@ \file gd32f4xx_dac.h \brief definitions for the DAC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -40,155 +38,155 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* DACx(x=0,1) definitions */ -#define DAC DAC_BASE -#define DAC0 0U -#define DAC1 1U +#define DAC DAC_BASE +#define DAC0 0U +#define DAC1 1U /* registers definitions */ -#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ -#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ -#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ -#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ -#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ -#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ -#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ -#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ -#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ -#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ -#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ -#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 data output register */ -#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 data output register */ -#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 data output register */ +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 data output register */ +#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ /* bits definitions */ /* DAC_CTL */ -#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ -#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ -#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ -#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ -#define DAC_CTL_DWM0 BITS(6,7) /*!< DAC0 noise wave mode */ -#define DAC_CTL_DWBW0 BITS(8,11) /*!< DAC0 noise wave bit width */ -#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disable bit */ -#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun interrupt enable/disable bit */ -#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ -#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ -#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ -#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ -#define DAC_CTL_DWM1 BITS(22,23) /*!< DAC1 noise wave mode */ -#define DAC_CTL_DWBW1 BITS(24,27) /*!< DAC1 noise wave bit width */ -#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ -#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM0 BITS(6,7) /*!< DAC0 noise wave mode */ +#define DAC_CTL_DWBW0 BITS(8,11) /*!< DAC0 noise wave bit width */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun interrupt enable/disable bit */ +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM1 BITS(22,23) /*!< DAC1 noise wave mode */ +#define DAC_CTL_DWBW1 BITS(24,27) /*!< DAC1 noise wave bit width */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ /* DAC_SWT */ -#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit, cleared by hardware */ -#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit, cleared by hardware */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit, cleared by hardware */ +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit, cleared by hardware */ /* DAC0_R12DH */ -#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ /* DAC0_L12DH */ -#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ /* DAC0_R8DH */ -#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ /* DAC1_R12DH */ -#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ /* DAC1_L12DH */ -#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ /* DAC1_R8DH */ -#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ /* DACC_R12DH */ -#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ -#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ /* DACC_L12DH */ -#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ -#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ /* DACC_R8DH */ -#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ -#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ /* DAC0_DO */ -#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ /* DAC1_DO */ -#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ /* DAC_STAT */ -#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ -#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ +#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ +#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ /* constants definitions */ /* DAC trigger source */ -#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) -#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ -#define DAC_TRIGGER_T7_TRGO CTL_DTSEL(1) /*!< TIMER7 TRGO */ -#define DAC_TRIGGER_T6_TRGO CTL_DTSEL(2) /*!< TIMER6 TRGO */ -#define DAC_TRIGGER_T4_TRGO CTL_DTSEL(3) /*!< TIMER4 TRGO */ -#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ -#define DAC_TRIGGER_T3_TRGO CTL_DTSEL(5) /*!< TIMER3 TRGO */ -#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ -#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */ +#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ +#define DAC_TRIGGER_T7_TRGO CTL_DTSEL(1) /*!< TIMER7 TRGO */ +#define DAC_TRIGGER_T6_TRGO CTL_DTSEL(2) /*!< TIMER6 TRGO */ +#define DAC_TRIGGER_T4_TRGO CTL_DTSEL(3) /*!< TIMER4 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_T3_TRGO CTL_DTSEL(5) /*!< TIMER3 TRGO */ +#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< software trigger */ /* DAC noise wave mode */ -#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) -#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disable */ -#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */ -#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */ +#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disable */ +#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */ +#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */ /* DAC noise wave bit width */ -#define DWBW(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) -#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */ -#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */ -#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */ -#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */ -#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */ -#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */ -#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */ -#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */ -#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */ -#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */ -#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */ -#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */ +#define DWBW(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */ +#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */ +#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */ +#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */ +#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */ +#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */ +#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */ +#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */ +#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */ +#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */ +#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */ +#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */ /* unmask LFSR bits in DAC LFSR noise mode */ -#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */ -#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */ -#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */ -#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */ -#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */ -#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */ -#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */ -#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */ -#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */ -#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */ -#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */ -#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */ +#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */ +#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */ +#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */ +#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */ +#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */ +#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */ +#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */ +#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */ +#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */ +#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */ +#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */ +#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */ /* DAC data alignment */ -#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) -#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12 bit alignment */ -#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12 bit alignment */ -#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8 bit alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12 bit alignment */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12 bit alignment */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8 bit alignment */ /* triangle amplitude in DAC triangle noise mode */ -#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */ -#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */ -#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */ -#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */ -#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */ -#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */ -#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */ -#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */ -#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */ -#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */ -#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */ -#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */ +#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */ +#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */ +#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */ +#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */ +#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */ +#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */ +#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */ +#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */ +#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */ +#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */ +#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */ +#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */ /* function declarations */ /* initialization functions */ @@ -254,14 +252,14 @@ void dac_concurrent_interrupt_enable(void); void dac_concurrent_interrupt_disable(void); /* DAC interrupt configuration */ -/* enable DAC interrupt(DAC DMA underrun interrupt) */ -void dac_interrupt_enable(uint32_t dac_periph); -/* disable DAC interrupt(DAC DMA underrun interrupt) */ -void dac_interrupt_disable(uint32_t dac_periph); /* get the specified DAC flag(DAC DMA underrun flag) */ FlagStatus dac_flag_get(uint32_t dac_periph); /* clear the specified DAC flag(DAC DMA underrun flag) */ void dac_flag_clear(uint32_t dac_periph); +/* enable DAC interrupt(DAC DMA underrun interrupt) */ +void dac_interrupt_enable(uint32_t dac_periph); +/* disable DAC interrupt(DAC DMA underrun interrupt) */ +void dac_interrupt_disable(uint32_t dac_periph); /* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ FlagStatus dac_interrupt_flag_get(uint32_t dac_periph); /* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h index aeb31b5..315a420 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h @@ -2,13 +2,11 @@ \file gd32f4xx_dbg.h \brief definitions for the DBG - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -57,7 +55,6 @@ OF SUCH DAMAGE. #define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ #define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ #define DBG_CTL0_TRACE_IOEN BIT(5) /*!< enable trace pin assignment */ -#define DBG_CTL0_TRACE_MODE BITS(6,7) /*!< trace pin mode selection */ /* DBG_CTL1 */ #define DBG_CTL1_TIMER1_HOLD BIT(0) /*!< hold TIMER1 counter when core is halted */ @@ -122,19 +119,13 @@ typedef enum DBG_I2C2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 23U), /*!< hold I2C2 smbus when core is halted */ DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 25U), /*!< debug CAN0 kept when core is halted */ DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 26U), /*!< debug CAN1 kept when core is halted */ - DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 0U), /*!< hold TIMER0 counter when core is halted */ - DBG_TIMER7_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 1U), /*!< hold TIMER7 counter when core is halted */ - DBG_TIMER8_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 16U), /*!< hold TIMER8 counter when core is halted */ - DBG_TIMER9_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 17U), /*!< hold TIMER9 counter when core is halted */ - DBG_TIMER10_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 18U) /*!< hold TIMER10 counter when core is halted */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 0U), /*!< hold TIMER0 counter when core is halted */ + DBG_TIMER7_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 1U), /*!< hold TIMER7 counter when core is halted */ + DBG_TIMER8_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 16U), /*!< hold TIMER8 counter when core is halted */ + DBG_TIMER9_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 17U), /*!< hold TIMER9 counter when core is halted */ + DBG_TIMER10_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 18U) /*!< hold TIMER10 counter when core is halted */ }dbg_periph_enum; -#define CTL0_TRACE_MODE(regval) (BITS(6,7)&((uint32_t)(regval)<<6)) -#define TRACE_MODE_ASYNC CTL0_TRACE_MODE(0) /*!< trace pin used for async mode */ -#define TRACE_MODE_SYNC_DATASIZE_1 CTL0_TRACE_MODE(1) /*!< trace pin used for sync mode and data size is 1 */ -#define TRACE_MODE_SYNC_DATASIZE_2 CTL0_TRACE_MODE(2) /*!< trace pin used for sync mode and data size is 2 */ -#define TRACE_MODE_SYNC_DATASIZE_4 CTL0_TRACE_MODE(3) /*!< trace pin used for sync mode and data size is 4 */ - /* function declarations */ /* deinitialize the DBG */ void dbg_deinit(void); @@ -155,7 +146,5 @@ void dbg_periph_disable(dbg_periph_enum dbg_periph); void dbg_trace_pin_enable(void); /* disable trace pin assignment */ void dbg_trace_pin_disable(void); -/* set trace pin mode */ -void dbg_trace_pin_mode_set(uint32_t trace_mode); #endif /* GD32F4XX_DBG_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h index 3fa215a..ac32060 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h @@ -2,13 +2,11 @@ \file gd32f4xx_dci.h \brief definitions for the DCI - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h index 04c0c53..06b864a 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h @@ -1,14 +1,11 @@ /*! - \file gd32f4xx_dma.c + \file gd32f4xx_dma.h \brief definitions for the DMA - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -37,73 +34,77 @@ OF SUCH DAMAGE. #ifndef GD32F4XX_DMA_H #define GD32F4XX_DMA_H +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ #include "gd32f4xx.h" + /* DMA definitions */ -#define DMA0 (DMA_BASE) /*!< DMA0 base address */ -#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x00000400U) /*!< DMA1 base address */ /* registers definitions */ -#define DMA_INTF0(dmax) REG32((dmax) + 0x00U) /*!< DMA interrupt flag register 0 */ -#define DMA_INTF1(dmax) REG32((dmax) + 0x04U) /*!< DMA interrupt flag register 1 */ -#define DMA_INTC0(dmax) REG32((dmax) + 0x08U) /*!< DMA interrupt flag clear register 0 */ -#define DMA_INTC1(dmax) REG32((dmax) + 0x0CU) /*!< DMA interrupt flag clear register 1 */ - -#define DMA_CH0CTL(dmax) REG32((dmax) + 0x10U) /*!< DMA channel 0 control register */ -#define DMA_CH0CNT(dmax) REG32((dmax) + 0x14U) /*!< DMA channel 0 counter register */ -#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x18U) /*!< DMA channel 0 peripheral base address register */ -#define DMA_CH0M0ADDR(dmax) REG32((dmax) + 0x1CU) /*!< DMA channel 0 memory 0 base address register */ -#define DMA_CH0M1ADDR(dmax) REG32((dmax) + 0x20U) /*!< DMA channel 0 memory 1 base address register */ -#define DMA_CH0FCTL(dmax) REG32((dmax) + 0x24U) /*!< DMA channel 0 FIFO control register */ - -#define DMA_CH1CTL(dmax) REG32((dmax) + 0x28U) /*!< DMA channel 1 control register */ -#define DMA_CH1CNT(dmax) REG32((dmax) + 0x2CU) /*!< DMA channel 1 counter register */ -#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x30U) /*!< DMA channel 1 peripheral base address register */ -#define DMA_CH1M0ADDR(dmax) REG32((dmax) + 0x34U) /*!< DMA channel 1 memory 0 base address register */ -#define DMA_CH1M1ADDR(dmax) REG32((dmax) + 0x38U) /*!< DMA channel 1 memory 1 base address register */ -#define DMA_CH1FCTL(dmax) REG32((dmax) + 0x3CU) /*!< DMA channel 1 FIFO control register */ - -#define DMA_CH2CTL(dmax) REG32((dmax) + 0x40U) /*!< DMA channel 2 control register */ -#define DMA_CH2CNT(dmax) REG32((dmax) + 0x44U) /*!< DMA channel 2 counter register */ -#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x48U) /*!< DMA channel 2 peripheral base address register */ -#define DMA_CH2M0ADDR(dmax) REG32((dmax) + 0x4CU) /*!< DMA channel 2 memory 0 base address register */ -#define DMA_CH2M1ADDR(dmax) REG32((dmax) + 0x50U) /*!< DMA channel 2 memory 1 base address register */ -#define DMA_CH2FCTL(dmax) REG32((dmax) + 0x54U) /*!< DMA channel 2 FIFO control register */ - -#define DMA_CH3CTL(dmax) REG32((dmax) + 0x58U) /*!< DMA channel 3 control register */ -#define DMA_CH3CNT(dmax) REG32((dmax) + 0x5CU) /*!< DMA channel 3 counter register */ -#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x60U) /*!< DMA channel 3 peripheral base address register */ -#define DMA_CH3M0ADDR(dmax) REG32((dmax) + 0x64U) /*!< DMA channel 3 memory 0 base address register */ -#define DMA_CH3M1ADDR(dmax) REG32((dmax) + 0x68U) /*!< DMA channel 3 memory 1 base address register */ -#define DMA_CH3FCTL(dmax) REG32((dmax) + 0x6CU) /*!< DMA channel 3 FIFO control register */ - -#define DMA_CH4CTL(dmax) REG32((dmax) + 0x70U) /*!< DMA channel 4 control register */ -#define DMA_CH4CNT(dmax) REG32((dmax) + 0x74U) /*!< DMA channel 4 counter register */ -#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x78U) /*!< DMA channel 4 peripheral base address register */ -#define DMA_CH4M0ADDR(dmax) REG32((dmax) + 0x7CU) /*!< DMA channel 4 memory 0 base address register */ -#define DMA_CH4M1ADDR(dmax) REG32((dmax) + 0x80U) /*!< DMA channel 4 memory 1 base address register */ -#define DMA_CH4FCTL(dmax) REG32((dmax) + 0x84U) /*!< DMA channel 4 FIFO control register */ - -#define DMA_CH5CTL(dmax) REG32((dmax) + 0x88U) /*!< DMA channel 5 control register */ -#define DMA_CH5CNT(dmax) REG32((dmax) + 0x8CU) /*!< DMA channel 5 counter register */ -#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x90U) /*!< DMA channel 5 peripheral base address register */ -#define DMA_CH5M0ADDR(dmax) REG32((dmax) + 0x94U) /*!< DMA channel 5 memory 0 base address register */ -#define DMA_CH5M1ADDR(dmax) REG32((dmax) + 0x98U) /*!< DMA channel 5 memory 1 base address register */ -#define DMA_CH5FCTL(dmax) REG32((dmax) + 0x9CU) /*!< DMA channel 5 FIFO control register */ - -#define DMA_CH6CTL(dmax) REG32((dmax) + 0xA0U) /*!< DMA channel 6 control register */ -#define DMA_CH6CNT(dmax) REG32((dmax) + 0xA4U) /*!< DMA channel 6 counter register */ -#define DMA_CH6PADDR(dmax) REG32((dmax) + 0xA8U) /*!< DMA channel 6 peripheral base address register */ -#define DMA_CH6M0ADDR(dmax) REG32((dmax) + 0xACU) /*!< DMA channel 6 memory 0 base address register */ -#define DMA_CH6M1ADDR(dmax) REG32((dmax) + 0xB0U) /*!< DMA channel 6 memory 1 base address register */ -#define DMA_CH6FCTL(dmax) REG32((dmax) + 0xB4U) /*!< DMA channel 6 FIFO control register */ - -#define DMA_CH7CTL(dmax) REG32((dmax) + 0xB8U) /*!< DMA channel 7 control register */ -#define DMA_CH7CNT(dmax) REG32((dmax) + 0xBCU) /*!< DMA channel 7 counter register */ -#define DMA_CH7PADDR(dmax) REG32((dmax) + 0xC0U) /*!< DMA channel 7 peripheral base address register */ -#define DMA_CH7M0ADDR(dmax) REG32((dmax) + 0xC4U) /*!< DMA channel 7 memory 0 base address register */ -#define DMA_CH7M1ADDR(dmax) REG32((dmax) + 0xC8U) /*!< DMA channel 7 memory 1 base address register */ -#define DMA_CH7FCTL(dmax) REG32((dmax) + 0xCCU) /*!< DMA channel 7 FIFO control register */ +#define DMA_INTF0(dmax) REG32((dmax) + 0x00000000U) /*!< DMA interrupt flag register 0 */ +#define DMA_INTF1(dmax) REG32((dmax) + 0x00000004U) /*!< DMA interrupt flag register 1 */ +#define DMA_INTC0(dmax) REG32((dmax) + 0x00000008U) /*!< DMA interrupt flag clear register 0 */ +#define DMA_INTC1(dmax) REG32((dmax) + 0x0000000CU) /*!< DMA interrupt flag clear register 1 */ + +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x00000010U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x00000014U) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x00000018U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0M0ADDR(dmax) REG32((dmax) + 0x0000001CU) /*!< DMA channel 0 memory 0 base address register */ +#define DMA_CH0M1ADDR(dmax) REG32((dmax) + 0x00000020U) /*!< DMA channel 0 memory 1 base address register */ +#define DMA_CH0FCTL(dmax) REG32((dmax) + 0x00000024U) /*!< DMA channel 0 FIFO control register */ + +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x00000028U) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x0000002CU) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x00000030U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1M0ADDR(dmax) REG32((dmax) + 0x00000034U) /*!< DMA channel 1 memory 0 base address register */ +#define DMA_CH1M1ADDR(dmax) REG32((dmax) + 0x00000038U) /*!< DMA channel 1 memory 1 base address register */ +#define DMA_CH1FCTL(dmax) REG32((dmax) + 0x0000003CU) /*!< DMA channel 1 FIFO control register */ + +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x00000040U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x00000044U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x00000048U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2M0ADDR(dmax) REG32((dmax) + 0x0000004CU) /*!< DMA channel 2 memory 0 base address register */ +#define DMA_CH2M1ADDR(dmax) REG32((dmax) + 0x00000050U) /*!< DMA channel 2 memory 1 base address register */ +#define DMA_CH2FCTL(dmax) REG32((dmax) + 0x00000054U) /*!< DMA channel 2 FIFO control register */ + +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x00000058U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x0000005CU) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x00000060U) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3M0ADDR(dmax) REG32((dmax) + 0x00000064U) /*!< DMA channel 3 memory 0 base address register */ +#define DMA_CH3M1ADDR(dmax) REG32((dmax) + 0x00000068U) /*!< DMA channel 3 memory 1 base address register */ +#define DMA_CH3FCTL(dmax) REG32((dmax) + 0x0000006CU) /*!< DMA channel 3 FIFO control register */ + +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x00000070U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x00000074U) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x00000078U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4M0ADDR(dmax) REG32((dmax) + 0x0000007CU) /*!< DMA channel 4 memory 0 base address register */ +#define DMA_CH4M1ADDR(dmax) REG32((dmax) + 0x00000080U) /*!< DMA channel 4 memory 1 base address register */ +#define DMA_CH4FCTL(dmax) REG32((dmax) + 0x00000084U) /*!< DMA channel 4 FIFO control register */ + +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x00000088U) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x0000008CU) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x00000090U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5M0ADDR(dmax) REG32((dmax) + 0x00000094U) /*!< DMA channel 5 memory 0 base address register */ +#define DMA_CH5M1ADDR(dmax) REG32((dmax) + 0x00000098U) /*!< DMA channel 5 memory 1 base address register */ +#define DMA_CH5FCTL(dmax) REG32((dmax) + 0x0000009CU) /*!< DMA channel 5 FIFO control register */ + +#define DMA_CH6CTL(dmax) REG32((dmax) + 0x000000A0U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0x000000A4U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0x000000A8U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6M0ADDR(dmax) REG32((dmax) + 0x000000ACU) /*!< DMA channel 6 memory 0 base address register */ +#define DMA_CH6M1ADDR(dmax) REG32((dmax) + 0x000000B0U) /*!< DMA channel 6 memory 1 base address register */ +#define DMA_CH6FCTL(dmax) REG32((dmax) + 0x000000B4U) /*!< DMA channel 6 FIFO control register */ + +#define DMA_CH7CTL(dmax) REG32((dmax) + 0x000000B8U) /*!< DMA channel 7 control register */ +#define DMA_CH7CNT(dmax) REG32((dmax) + 0x000000BCU) /*!< DMA channel 7 counter register */ +#define DMA_CH7PADDR(dmax) REG32((dmax) + 0x000000C0U) /*!< DMA channel 7 peripheral base address register */ +#define DMA_CH7M0ADDR(dmax) REG32((dmax) + 0x000000C4U) /*!< DMA channel 7 memory 0 base address register */ +#define DMA_CH7M1ADDR(dmax) REG32((dmax) + 0x000000C8U) /*!< DMA channel 7 memory 1 base address register */ +#define DMA_CH7FCTL(dmax) REG32((dmax) + 0x000000CCU) /*!< DMA channel 7 FIFO control register */ /* bits definitions */ /* DMA_INTF */ @@ -326,7 +327,7 @@ typedef struct #define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ #define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ #define DMA_CHINTF_RESET_VALUE ((uint32_t)0x0000003DU) /*!< clear DMA channel CHXINTFS register */ -#define DMA_CHFCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXFCTL register */ +#define DMA_CHFCTL_RESET_VALUE ((uint32_t)0x00000021U) /*!< the reset value of DMA channel CHXFCTL register */ /* DMA_INTF register */ /* interrupt flag bits */ @@ -416,13 +417,17 @@ uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx); FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); /* clear DMA a channel flag */ void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); -/* check DMA flag is set or not */ -FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); -/* clear DMA a channel flag */ -void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); /* enable DMA interrupt */ void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); /* disable DMA interrupt */ void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); +/* check DMA flag is set or not */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ #endif /* GD32F4XX_DMA_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h index 6cd948f..225294c 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h @@ -2,13 +2,11 @@ \file gd32f4xx_enet.h \brief definitions for the ENET - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -46,11 +44,11 @@ OF SUCH DAMAGE. #endif #ifndef ENET_RXBUF_NUM -#define ENET_RXBUF_NUM 2U /*!< ethernet Rx DMA descriptor number */ +#define ENET_RXBUF_NUM 5U /*!< ethernet Rx DMA descriptor number */ #endif #ifndef ENET_TXBUF_NUM -#define ENET_TXBUF_NUM 1U /*!< ethernet Tx DMA descriptor number */ +#define ENET_TXBUF_NUM 5U /*!< ethernet Tx DMA descriptor number */ #endif #ifndef ENET_RXBUF_SIZE @@ -129,7 +127,7 @@ OF SUCH DAMAGE. #define ENET_MAC_HLH REG32((ENET) + 0x0008U) /*!< ethernet MAC hash list high register */ #define ENET_MAC_HLL REG32((ENET) + 0x000CU) /*!< ethernet MAC hash list low register */ #define ENET_MAC_PHY_CTL REG32((ENET) + 0x0010U) /*!< ethernet MAC PHY control register */ -#define ENET_MAC_PHY_DATA REG32((ENET) + 0x0014U) /*!< ethernet MAC MII data register */ +#define ENET_MAC_PHY_DATA REG32((ENET) + 0x0014U) /*!< ethernet MAC PHY data register */ #define ENET_MAC_FCTL REG32((ENET) + 0x0018U) /*!< ethernet MAC flow control register */ #define ENET_MAC_VLT REG32((ENET) + 0x001CU) /*!< ethernet MAC VLAN tag register */ #define ENET_MAC_RWFF REG32((ENET) + 0x0028U) /*!< ethernet MAC remote wakeup frame filter register */ @@ -891,8 +889,8 @@ typedef enum { ENET_PROMISCUOUS_MODE = ENET_MAC_FRMF_PM, /*!< promiscuous mode enabled */ ENET_RECEIVEALL = (int32_t)ENET_MAC_FRMF_FAR, /*!< all received frame are forwarded to application */ - ENET_CUSTOM = BIT(4), - ENET_BROADCAST_FRAMES_PASS = (uint32_t)0x00000000U, /*!< the address filters pass all received broadcast frames */ + ENET_CUSTOM = BIT(4), /** AvV **/ + ENET_BROADCAST_FRAMES_PASS = (uint32_t)0x00000000U, /*!< the address filters pass all received broadcast frames */ ENET_BROADCAST_FRAMES_DROP = ENET_MAC_FRMF_BFRMD /*!< the address filters filter all incoming broadcast frames */ }enet_frmrecept_enum; @@ -1119,7 +1117,7 @@ typedef struct #define ENET_MDC_HCLK_DIV62 MAC_PHY_CTL_CLR(1) /*!< HCLK:100-150 MHz; MDC clock= HCLK/62 */ #define ENET_MDC_HCLK_DIV16 MAC_PHY_CTL_CLR(2) /*!< HCLK:20-35 MHz; MDC clock= HCLK/16 */ #define ENET_MDC_HCLK_DIV26 MAC_PHY_CTL_CLR(3) /*!< HCLK:35-60 MHz; MDC clock= HCLK/26 */ -#define ENET_MDC_HCLK_DIV102 MAC_PHY_CTL_CLR(4) /*!< HCLK:150-200 MHz; MDC clock= HCLK/102 */ +#define ENET_MDC_HCLK_DIV102 MAC_PHY_CTL_CLR(4) /*!< HCLK:150-240 MHz; MDC clock= HCLK/102 */ #define MAC_PHY_CTL_PR(regval) (BITS(6,10) & ((uint32_t)(regval) << 6)) /*!< write value to ENET_MAC_PHY_CTL_PR bit field */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h index 39c5abc..6abedbc 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h @@ -2,13 +2,11 @@ \file gd32f4xx_exmc.h \brief definitions for the EXMC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -113,13 +111,13 @@ OF SUCH DAMAGE. #define EXMC_SNCTL_NRWTPOL BIT(9) /*!< NWAIT signal polarity */ #define EXMC_SNCTL_WRAPEN BIT(10) /*!< wrapped burst mode enable */ #define EXMC_SNCTL_NRWTCFG BIT(11) /*!< NWAIT signal configuration, only work in synchronous mode */ -#define EXMC_SNCTL_WREN BIT(12) /*!< write enable */ +#define EXMC_SNCTL_WEN BIT(12) /*!< write enable */ #define EXMC_SNCTL_NRWTEN BIT(13) /*!< NWAIT signal enable */ #define EXMC_SNCTL_EXMODEN BIT(14) /*!< extended mode enable */ -#define EXMC_SNCTL_ASYNCWAIT BIT(15) /*!< asynchronous wait enable */ +#define EXMC_SNCTL_ASYNCWTEN BIT(15) /*!< asynchronous wait enable */ #define EXMC_SNCTL_CPS BITS(16,18) /*!< CRAM page size */ -#define EXMC_SNCTL_SYNCWR BIT(19) /*!< synchronous write config */ -#define EXMC_SNCTL_CCK BIT(20) /*!< consecutive clock config */ +#define EXMC_SNCTL_SYNCWR BIT(19) /*!< synchronous write configuration */ +#define EXMC_SNCTL_CCK BIT(20) /*!< consecutive clock configuration */ /* EXMC_SNTCFGx,x=0..3 */ #define EXMC_SNTCFG_ASET BITS(0,3) /*!< asynchronous address setup time */ @@ -207,7 +205,7 @@ OF SUCH DAMAGE. /* EXMC_SDARI */ #define EXMC_SDARI_REC BIT(0) /*!< refresh error flag clear */ #define EXMC_SDARI_ARINTV BITS(1,13) /*!< auto-refresh interval */ -#define EXMC_SDARI_REIE BIT(14) /*!< interrupt refresh error enable */ +#define EXMC_SDARI_REIE BIT(14) /*!< refresh error interrupt enable */ /* EXMC_SDSTAT */ #define EXMC_SDSDAT_REIF BIT(0) /*!< refresh error interrupt flag */ @@ -278,7 +276,7 @@ typedef struct exmc_norsram_timing_parameter_struct* write_timing; /*!< timing parameters for write when the extendedmode is used. */ }exmc_norsram_parameter_struct; -/* EXMC NAND/PC card timing initialize struct */ +/* EXMC NAND/PC card timing initialize structure */ typedef struct { uint32_t databus_hiztime; /*!< configure the dadtabus HiZ time for write operation */ @@ -287,7 +285,7 @@ typedef struct uint32_t setuptime; /*!< configure the address setup time */ }exmc_nand_pccard_timing_parameter_struct; -/* EXMC NAND initialize struct */ +/* EXMC NAND initialize structure */ typedef struct { uint32_t nand_bank; /*!< select the bank of NAND */ @@ -301,7 +299,7 @@ typedef struct exmc_nand_pccard_timing_parameter_struct* attribute_space_timing; /*!< the timing parameters for NAND flash attribute space */ }exmc_nand_parameter_struct; -/* EXMC PC card initialize struct */ +/* EXMC PC card initialize structure */ typedef struct { uint32_t atr_latency; /*!< configure the latency of ALE low to RB low */ @@ -312,7 +310,7 @@ typedef struct exmc_nand_pccard_timing_parameter_struct* io_space_timing; /*!< the timing parameters for PC card IO space */ }exmc_pccard_parameter_struct; -/* EXMC SDRAM timing initialize struct */ +/* EXMC SDRAM timing initialize structure */ typedef struct { uint32_t row_to_column_delay; /*!< configure the row to column delay */ @@ -324,12 +322,12 @@ typedef struct uint32_t load_mode_register_delay; /*!< configure the load mode register delay */ }exmc_sdram_timing_parameter_struct; -/* EXMC SDRAM initialize struct */ +/* EXMC SDRAM initialize structure */ typedef struct { uint32_t sdram_device; /*!< device of SDRAM */ uint32_t pipeline_read_delay; /*!< the delay for reading data after CAS latency in HCLK clock cycles */ - uint32_t brust_read_switch; /*!< enable or disable the burst read */ + uint32_t burst_read_switch; /*!< enable or disable the burst read */ uint32_t sdclock_config; /*!< the SDCLK memory clock for both SDRAM banks */ uint32_t write_protection; /*!< enable or disable SDRAM bank write protection function */ uint32_t cas_latency; /*!< configure the SDRAM CAS latency */ @@ -340,7 +338,7 @@ typedef struct exmc_sdram_timing_parameter_struct* timing; /*!< the timing parameters for write and read SDRAM */ }exmc_sdram_parameter_struct; -/* EXMC SDRAM command initialize struct */ +/* EXMC SDRAM command initialize structure */ typedef struct { uint32_t mode_register_content; /*!< the SDRAM mode register content */ @@ -349,7 +347,7 @@ typedef struct uint32_t command; /*!< the commands that will be sent to SDRAM */ }exmc_sdram_command_parameter_struct; -/* EXMC SQPISRAM initialize struct */ +/* EXMC SQPISRAM initialize structure */ typedef struct{ uint32_t sample_polarity; /*!< read data sample polarity */ uint32_t id_length; /*!< SPI PSRAM ID length */ @@ -357,7 +355,7 @@ typedef struct{ uint32_t command_bits; /*!< bit number of SPI PSRAM command phase */ }exmc_sqpipsram_parameter_struct; -/* EXMC_register address */ +/* EXMC register address */ #define EXMC_SNCTL(region) REG32(EXMC + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash control registers, region = 0,1,2,3 */ #define EXMC_SNTCFG(region) REG32(EXMC + 0x04U + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash timing configuration registers, region = 0,1,2,3 */ #define EXMC_SNWTCFG(region) REG32(EXMC + 0x104U + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash write timing configuration registers, region = 0,1,2,3 */ @@ -419,21 +417,21 @@ typedef struct{ /* synchronous clock divide ratio */ #define SNTCFG_CKDIV(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) #define EXMC_SYN_CLOCK_RATIO_DISABLE SNTCFG_CKDIV(0) /*!< EXMC_CLK disable */ -#define EXMC_SYN_CLOCK_RATIO_2_CLK SNTCFG_CKDIV(1) /*!< EXMC_CLK = HCLK/2 */ -#define EXMC_SYN_CLOCK_RATIO_3_CLK SNTCFG_CKDIV(2) /*!< EXMC_CLK = HCLK/3 */ -#define EXMC_SYN_CLOCK_RATIO_4_CLK SNTCFG_CKDIV(3) /*!< EXMC_CLK = HCLK/4 */ -#define EXMC_SYN_CLOCK_RATIO_5_CLK SNTCFG_CKDIV(4) /*!< EXMC_CLK = HCLK/5 */ -#define EXMC_SYN_CLOCK_RATIO_6_CLK SNTCFG_CKDIV(5) /*!< EXMC_CLK = HCLK/6 */ -#define EXMC_SYN_CLOCK_RATIO_7_CLK SNTCFG_CKDIV(6) /*!< EXMC_CLK = HCLK/7 */ -#define EXMC_SYN_CLOCK_RATIO_8_CLK SNTCFG_CKDIV(7) /*!< EXMC_CLK = HCLK/8 */ -#define EXMC_SYN_CLOCK_RATIO_9_CLK SNTCFG_CKDIV(8) /*!< EXMC_CLK = HCLK/9 */ -#define EXMC_SYN_CLOCK_RATIO_10_CLK SNTCFG_CKDIV(9) /*!< EXMC_CLK = HCLK/10 */ -#define EXMC_SYN_CLOCK_RATIO_11_CLK SNTCFG_CKDIV(10) /*!< EXMC_CLK = HCLK/11 */ -#define EXMC_SYN_CLOCK_RATIO_12_CLK SNTCFG_CKDIV(11) /*!< EXMC_CLK = HCLK/12 */ -#define EXMC_SYN_CLOCK_RATIO_13_CLK SNTCFG_CKDIV(12) /*!< EXMC_CLK = HCLK/13 */ -#define EXMC_SYN_CLOCK_RATIO_14_CLK SNTCFG_CKDIV(13) /*!< EXMC_CLK = HCLK/14 */ -#define EXMC_SYN_CLOCK_RATIO_15_CLK SNTCFG_CKDIV(14) /*!< EXMC_CLK = HCLK/15 */ -#define EXMC_SYN_CLOCK_RATIO_16_CLK SNTCFG_CKDIV(15) /*!< EXMC_CLK = HCLK/16 */ +#define EXMC_SYN_CLOCK_RATIO_2_CLK SNTCFG_CKDIV(1) /*!< EXMC_CLK = 2*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_3_CLK SNTCFG_CKDIV(2) /*!< EXMC_CLK = 3*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_4_CLK SNTCFG_CKDIV(3) /*!< EXMC_CLK = 4*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_5_CLK SNTCFG_CKDIV(4) /*!< EXMC_CLK = 5*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_6_CLK SNTCFG_CKDIV(5) /*!< EXMC_CLK = 6*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_7_CLK SNTCFG_CKDIV(6) /*!< EXMC_CLK = 7*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_8_CLK SNTCFG_CKDIV(7) /*!< EXMC_CLK = 8*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_9_CLK SNTCFG_CKDIV(8) /*!< EXMC_CLK = 9*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_10_CLK SNTCFG_CKDIV(9) /*!< EXMC_CLK = 10*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_11_CLK SNTCFG_CKDIV(10) /*!< EXMC_CLK = 11*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_12_CLK SNTCFG_CKDIV(11) /*!< EXMC_CLK = 12*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_13_CLK SNTCFG_CKDIV(12) /*!< EXMC_CLK = 13*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_14_CLK SNTCFG_CKDIV(13) /*!< EXMC_CLK = 14*HCLK*/ +#define EXMC_SYN_CLOCK_RATIO_15_CLK SNTCFG_CKDIV(14) /*!< EXMC_CLK = 15*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_16_CLK SNTCFG_CKDIV(15) /*!< EXMC_CLK = 16*HCLK */ /* ECC size */ #define NPCTL_ECCSZ(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) @@ -542,7 +540,7 @@ typedef struct{ #define EXMC_SDRAM_AUTO_REFLESH_14_SDCLK SDCMD_NARF(13) /*!< 14 auto-refresh cycles */ #define EXMC_SDRAM_AUTO_REFLESH_15_SDCLK SDCMD_NARF(14) /*!< 15 auto-refresh cycles */ -/* SDRAM command select */ +/* SDRAM command selection */ #define SDCMD_CMD(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) #define EXMC_SDRAM_NORMAL_OPERATION SDCMD_CMD(0) /*!< normal operation command */ #define EXMC_SDRAM_CLOCK_ENABLE SDCMD_CMD(1) /*!< clock enable command */ @@ -662,13 +660,13 @@ typedef struct{ #define EXMC_SDRAM_2_INTER_BANK ((uint32_t)0x00000000U) /*!< 2 internal banks */ #define EXMC_SDRAM_4_INTER_BANK EXMC_SDCTL_NBK /*!< 4 internal banks */ -/* SDRAM device0 select */ -#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device0 unselect */ -#define EXMC_SDRAM_DEVICE0_SELECT EXMC_SDCMD_DS0 /*!< SDRAM device0 select */ +/* SDRAM device0 selection */ +#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< unselect SDRAM device0 */ +#define EXMC_SDRAM_DEVICE0_SELECT EXMC_SDCMD_DS0 /*!< select SDRAM device0 */ -/* SDRAM device1 select */ -#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device1 unselect */ -#define EXMC_SDRAM_DEVICE1_SELECT EXMC_SDCMD_DS1 /*!< SDRAM device1 select */ +/* SDRAM device1 selection */ +#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< unselect SDRAM device1 */ +#define EXMC_SDRAM_DEVICE1_SELECT EXMC_SDCMD_DS1 /*!< select SDRAM device1 */ /* SDRAM device status */ #define EXMC_SDRAM_DEVICE_NORMAL ((uint32_t)0x00000000U) /*!< normal status */ @@ -717,7 +715,7 @@ void exmc_norsram_disable(uint32_t exmc_norsram_region); /* NAND */ /* deinitialize EXMC NAND bank */ void exmc_nand_deinit(uint32_t exmc_nand_bank); -/* initialize exmc_norsram_parameter_struct with the default values */ +/* initialize exmc_nand_parameter_struct with the default values */ void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struct); /* initialize EXMC NAND bank */ void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct); @@ -743,6 +741,8 @@ void exmc_sdram_deinit(uint32_t exmc_sdram_device); void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct); /* initialize EXMC SDRAM device */ void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct); +/* initialize exmc_sdram_command_parameter_struct with the default values */ +void exmc_sdram_struct_command_para_init(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct); /* SQPIPSRAM */ /* deinitialize EXMC SQPIPSRAM */ void exmc_sqpipsram_deinit(void); @@ -773,7 +773,7 @@ void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_c void exmc_sdram_refresh_count_set(uint32_t exmc_count); /* set the number of successive auto-refresh command */ void exmc_sdram_autorefresh_number_set(uint32_t exmc_number); -/* config the write protection function */ +/* configure the write protection function */ void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue); /* get the status of SDRAM device0 or device1 */ uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device); diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h index 70d941a..055af41 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h @@ -1,14 +1,11 @@ /*! \file gd32f4xx_exti.h \brief definitions for the EXTI - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.1, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -177,34 +174,33 @@ OF SUCH DAMAGE. #define EXTI_SWIEV_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */ /* EXTI_PD */ -#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ -#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ -#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ -#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ -#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ -#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ -#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ -#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ -#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ -#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ -#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ -#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ -#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ -#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ -#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ -#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ -#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ -#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ -#define EXTI_PD_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */ -#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ -#define EXTI_PD_PD20 BIT(20) /*!< interrupt/event pending status from line 20 */ -#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ -#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event pending status from line 22 */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt pending status from line 19 */ +#define EXTI_PD_PD20 BIT(20) /*!< interrupt pending status from line 20 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt pending status from line 22 */ /* constants definitions */ /* EXTI line number */ -typedef enum -{ +typedef enum { EXTI_0 = BIT(0), /*!< EXTI line 0 */ EXTI_1 = BIT(1), /*!< EXTI line 1 */ EXTI_2 = BIT(2), /*!< EXTI line 2 */ @@ -227,29 +223,27 @@ typedef enum EXTI_19 = BIT(19), /*!< EXTI line 19 */ EXTI_20 = BIT(20), /*!< EXTI line 20 */ EXTI_21 = BIT(21), /*!< EXTI line 21 */ - EXTI_22 = BIT(22), /*!< EXTI line 22 */ -}exti_line_enum; + EXTI_22 = BIT(22) /*!< EXTI line 22 */ +} exti_line_enum; /* external interrupt and event */ -typedef enum -{ +typedef enum { EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ EXTI_EVENT /*!< EXTI event mode */ -}exti_mode_enum; +} exti_mode_enum; /* interrupt trigger mode */ -typedef enum -{ +typedef enum { EXTI_TRIG_RISING = 0, /*!< EXTI rising edge trigger */ EXTI_TRIG_FALLING, /*!< EXTI falling edge trigger */ EXTI_TRIG_BOTH, /*!< EXTI rising and falling edge trigger */ EXTI_TRIG_NONE /*!< none EXTI edge trigger */ -}exti_trig_type_enum; +} exti_trig_type_enum; /* function declarations */ /* deinitialize the EXTI */ void exti_deinit(void); -/* enable the configuration of EXTI initialize */ +/* initialize the EXTI line x */ void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); /* enable the interrupts from EXTI line x */ void exti_interrupt_enable(exti_line_enum linex); @@ -259,19 +253,19 @@ void exti_interrupt_disable(exti_line_enum linex); void exti_event_enable(exti_line_enum linex); /* disable the events from EXTI line x */ void exti_event_disable(exti_line_enum linex); -/* EXTI software interrupt event enable */ +/* enable the software interrupt event from EXTI line x */ void exti_software_interrupt_enable(exti_line_enum linex); -/* EXTI software interrupt event disable */ +/* disable the software interrupt event from EXTI line x */ void exti_software_interrupt_disable(exti_line_enum linex); /* interrupt & flag functions */ -/* get EXTI lines pending flag */ +/* get EXTI line x interrupt pending flag */ FlagStatus exti_flag_get(exti_line_enum linex); -/* clear EXTI lines pending flag */ +/* clear EXTI line x interrupt pending flag */ void exti_flag_clear(exti_line_enum linex); -/* get EXTI lines flag when the interrupt flag is set */ +/* get EXTI line x interrupt pending flag */ FlagStatus exti_interrupt_flag_get(exti_line_enum linex); -/* clear EXTI lines pending flag */ +/* clear EXTI line x interrupt pending flag */ void exti_interrupt_flag_clear(exti_line_enum linex); #endif /* GD32F4XX_EXTI_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h index ac62970..192048d 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h @@ -2,36 +2,33 @@ \file gd32f4xx_fmc.h \brief definitions for the FMC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx - \version 2020-12-20, V2.1.1, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -46,15 +43,17 @@ OF SUCH DAMAGE. #define OB OB_BASE /*!< option byte base address */ /* registers definitions */ -#define FMC_WS REG32((FMC) + 0x0000U) /*!< FMC wait state register */ -#define FMC_KEY REG32((FMC) + 0x0004U) /*!< FMC unlock key register */ -#define FMC_OBKEY REG32((FMC) + 0x0008U) /*!< FMC option byte unlock key register */ -#define FMC_STAT REG32((FMC) + 0x000CU) /*!< FMC status register */ -#define FMC_CTL REG32((FMC) + 0x0010U) /*!< FMC control register */ -#define FMC_OBCTL0 REG32((FMC) + 0x0014U) /*!< FMC option byte control register 0 */ -#define FMC_OBCTL1 REG32((FMC) + 0x0018U) /*!< FMC option byte control register 1 */ -#define FMC_WSEN REG32((FMC) + 0x00FCU) /*!< FMC wait state enable register */ -#define FMC_PID REG32((FMC) + 0x0100U) /*!< FMC product ID register */ +#define FMC_WS REG32((FMC) + 0x00000000U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x00000004U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x00000008U) /*!< FMC option byte unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0000000CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x00000010U) /*!< FMC control register */ +#define FMC_OBCTL0 REG32((FMC) + 0x00000014U) /*!< FMC option byte control register 0 */ +#define FMC_OBCTL1 REG32((FMC) + 0x00000018U) /*!< FMC option byte control register 1 */ +#define FMC_PECFG REG32((FMC) + 0x00000020U) /*!< FMC page erase configuration register */ +#define FMC_PEKEY REG32((FMC) + 0x00000024U) /*!< FMC unlock page erase key register */ +#define FMC_WSEN REG32((FMC) + 0x000000FCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x00000100U) /*!< FMC product ID register */ #define OB_WP1 REG32((OB) + 0x00000008U) /*!< option byte write protection 1 */ #define OB_USER REG32((OB) + 0x00010000U) /*!< option byte user value*/ @@ -108,6 +107,13 @@ OF SUCH DAMAGE. /* FMC_OBCTL1 */ #define FMC_OBCTL1_WP1 BITS(16,27) /*!< erase/program protection of each sector when DRP is 0 */ +/* FMC_PECFG */ +#define FMC_PE_EN BIT(31) /*!< the enable bit of page erase function */ +#define FMC_PE_ADDR BITS(0,28) /*!< page erase address */ + +/* FMC_PEKEY */ +#define FMC_PE_KEY BITS(0,31) /*!< FMC_PECFG unlock key value */ + /* FMC_WSEN */ #define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ @@ -116,22 +122,21 @@ OF SUCH DAMAGE. /* constants definitions */ /* fmc state */ -typedef enum -{ - FMC_READY, /*!< the operation has been completed */ +typedef enum { + FMC_READY = 0, /*!< the operation has been completed */ FMC_BUSY, /*!< the operation is in progress */ FMC_RDDERR, /*!< read D-bus protection error */ FMC_PGSERR, /*!< program sequence error */ FMC_PGMERR, /*!< program size not match error */ FMC_WPERR, /*!< erase/program protection error */ FMC_OPERR, /*!< operation error */ - FMC_PGERR, /*!< program error */ - FMC_TOERR, /*!< timeout error */ -}fmc_state_enum; + FMC_TOERR /*!< timeout error */ +} fmc_state_enum; /* unlock key */ #define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ #define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ +#define UNLOCK_PE_KEY ((uint32_t)0xA9B8C7D6U) /*!< unlock page erase function key */ #define OB_UNLOCK_KEY0 ((uint32_t)0x08192A3BU) /*!< ob unlock key 0 */ #define OB_UNLOCK_KEY1 ((uint32_t)0x4C5D6E7FU) /*!< ob unlock key 1 */ @@ -171,7 +176,7 @@ typedef enum #define OB_BB_DISABLE OBCTL0_BB(0) /*!< boot from bank0 */ #define OB_BB_ENABLE OBCTL0_BB(1) /*!< boot from bank1 or bank0 if bank1 is void */ -/* option byte software/hardware free watch dog timer */ +/* option byte software/hardware free watch dog timer */ #define OBCTL0_NWDG_HW(regval) (BIT(5) & ((uint32_t)(regval))<< 5) #define OB_FWDGT_SW OBCTL0_NWDG_HW(1) /*!< software free watchdog */ #define OB_FWDGT_HW OBCTL0_NWDG_HW(0) /*!< hardware free watchdog */ @@ -243,14 +248,15 @@ typedef enum #define OB_DRP_21 ((uint32_t)0x02000000U) /*!< D-bus read protection protection of sector 21 */ #define OB_DRP_22 ((uint32_t)0x04000000U) /*!< D-bus read protection protection of sector 22 */ #define OB_DRP_23_27 ((uint32_t)0x08000000U) /*!< D-bus read protection protection of sector 23~27 */ +#define OB_DRP_ALL ((uint32_t)0x0FFF0FFFU) /*!< D-bus read protection protection of all sectors */ -/* double banks or single bank selection when flash size is 1M bytes */ -#define OBCTL0_DBS(regval) (BIT(30) & ((uint32_t)(regval)<<30)) +/* double banks or single bank selection when flash size is 1M bytes */ +#define OBCTL0_DBS(regval) (BIT(30) & ((uint32_t)(regval) << 30U)) #define OB_DBS_DISABLE OBCTL0_DBS(0) /*!< single bank when flash size is 1M bytes */ #define OB_DBS_ENABLE OBCTL0_DBS(1) /*!< double bank when flash size is 1M bytes */ -/* option bytes D-bus read protection mode */ -#define OBCTL0_DRP(regval) (BIT(31) & ((uint32_t)(regval)<<31)) +/* option bytes D-bus read protection mode */ +#define OBCTL0_DRP(regval) (BIT(31) & ((uint32_t)(regval) << 31U)) #define OB_DRP_DISABLE OBCTL0_DRP(0) /*!< the WPx bits used as erase/program protection of each sector */ #define OB_DRP_ENABLE OBCTL0_DRP(1) /*!< the WPx bits used as erase/program protection and D-bus read protection of each sector */ @@ -286,8 +292,8 @@ typedef enum #define CTL_SECTOR_NUMBER_23 CTL_SN(27) /*!< sector 23 */ -/* FMC program size */ -#define CTL_PSZ(regval) (BITS(8,9) & ((uint32_t)(regval))<< 8) +/* FMC program size */ +#define CTL_PSZ(regval) (BITS(8,9) & ((uint32_t)(regval))<< 8U) #define CTL_PSZ_BYTE CTL_PSZ(0) /*!< FMC program by byte access */ #define CTL_PSZ_HALF_WORD CTL_PSZ(1) /*!< FMC program by half-word access */ #define CTL_PSZ_WORD CTL_PSZ(2) /*!< FMC program by word access */ @@ -297,16 +303,25 @@ typedef enum #define FMC_INT_ERR ((uint32_t)0x02000000U) /*!< enable FMC error interrupt */ /* FMC flags */ -#define FMC_FLAG_END ((uint32_t)0x00000001U) /*!< FMC end of operation flag bit */ -#define FMC_FLAG_OPERR ((uint32_t)0x00000002U) /*!< FMC operation error flag bit */ -#define FMC_FLAG_WPERR ((uint32_t)0x00000010U) /*!< FMC erase/program protection error flag bit */ -#define FMC_FLAG_PGMERR ((uint32_t)0x00000040U) /*!< FMC program size not match error flag bit */ -#define FMC_FLAG_PGSERR ((uint32_t)0x00000080U) /*!< FMC program sequence error flag bit */ -#define FMC_FLAG_RDDERR ((uint32_t)0x00000100U) /*!< FMC read D-bus protection error flag bit */ -#define FMC_FLAG_BUSY ((uint32_t)0x00010000U) /*!< FMC busy flag */ +#define FMC_FLAG_END FMC_STAT_END /*!< FMC end of operation flag bit */ +#define FMC_FLAG_OPERR FMC_STAT_OPERR /*!< FMC operation error flag bit */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC erase/program protection error flag bit */ +#define FMC_FLAG_PGMERR FMC_STAT_PGMERR /*!< FMC program size not match error flag bit */ +#define FMC_FLAG_PGSERR FMC_STAT_PGSERR /*!< FMC program sequence error flag bit */ +#define FMC_FLAG_RDDERR FMC_STAT_RDDERR /*!< FMC read D-bus protection error flag bit */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ + +/* FMC interrupt flags */ +#define FMC_INT_FLAG_END FMC_STAT_END /*!< FMC end of operation interrupt flag */ +#define FMC_INT_FLAG_OPERR FMC_STAT_OPERR /*!< FMC operation error interrupt flag */ +#define FMC_INT_FLAG_WPERR FMC_STAT_WPERR /*!< FMC erase/program protection error interrupt flag */ +#define FMC_INT_FLAG_PGMERR FMC_STAT_PGMERR /*!< FMC program size not match error interrupt flag */ +#define FMC_INT_FLAG_PGSERR FMC_STAT_PGSERR /*!< FMC program sequence error interrupt flag */ +#define FMC_INT_FLAG_RDDERR FMC_STAT_RDDERR /*!< FMC read D-bus protection error interrupt flag */ + /* FMC time out */ -#define FMC_TIMEOUT_COUNT ((uint32_t)0xFFFFFFFFU) /*!< count to judge of FMC timeout */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x4FFFFFFFU) /*!< count to judge of FMC timeout */ /* function declarations */ /* FMC main memory programming functions */ @@ -316,6 +331,10 @@ void fmc_wscnt_set(uint32_t wscnt); void fmc_unlock(void); /* lock the main FMC operation */ void fmc_lock(void); +#if defined (GD32F425) || defined (GD32F427) || defined (GD32F470) +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_addr); +#endif /* FMC erase sector */ fmc_state_enum fmc_sector_erase(uint32_t fmc_sector); /* FMC erase whole chip */ @@ -341,22 +360,26 @@ void ob_start(void); /* erase option byte */ void ob_erase(void); /* enable write protect */ -void ob_write_protection_enable(uint32_t ob_wp); +ErrStatus ob_write_protection_enable(uint32_t ob_wp); /* disable write protect */ -void ob_write_protection_disable(uint32_t ob_wp); +ErrStatus ob_write_protection_disable(uint32_t ob_wp); /* enable erase/program protection and D-bus read protection */ void ob_drp_enable(uint32_t ob_drp); /* disable erase/program protection and D-bus read protection */ -void ob_drp_disable(uint32_t ob_drp); -/* set the option byte security protection level */ +void ob_drp_disable(void); +/* configure security protection level */ void ob_security_protection_config(uint8_t ob_spc); -/* write the FMC option byte user */ +/* program the FMC user option byte */ void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby); -/* option byte BOR threshold value */ +/* program the option byte BOR threshold value */ void ob_user_bor_threshold(uint32_t ob_bor_th); /* configure the boot mode */ void ob_boot_mode_config(uint32_t boot_mode); -/* get the FMC option byte user */ +#if defined (GD32F450) || defined (GD32F470) +/* configure the double bank select */ +void ob_double_bank_select(uint32_t double_bank); +#endif +/* get the FMC user option byte */ uint8_t ob_user_get(void); /* get the FMC option byte write protection */ uint16_t ob_write_protection0_get(void); @@ -368,21 +391,25 @@ uint16_t ob_drp0_get(void); uint16_t ob_drp1_get(void); /* get option byte security protection code value */ FlagStatus ob_spc_get(void); -/* get the FMC threshold value */ +/* get the FMC option byte BOR threshold value */ uint8_t ob_user_bor_threshold_get(void); /* FMC interrupts and flags management functions */ -/* enable FMC interrupt */ -void fmc_interrupt_enable(uint32_t fmc_int); -/* disable FMC interrupt */ -void fmc_interrupt_disable(uint32_t fmc_int); /* get flag set or reset */ FlagStatus fmc_flag_get(uint32_t fmc_flag); /* clear the FMC pending flag */ void fmc_flag_clear(uint32_t fmc_flag); -/* return the FMC state */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t fmc_int); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t fmc_int); +/* get FMC interrupt flag set or reset */ +FlagStatus fmc_interrupt_flag_get(uint32_t fmc_int_flag); +/* clear the FMC interrupt flag */ +void fmc_interrupt_flag_clear(uint32_t fmc_int_flag); +/* get the FMC state */ fmc_state_enum fmc_state_get(void); -/* check FMC ready or not */ +/* check whether FMC is ready or not */ fmc_state_enum fmc_ready_wait(uint32_t timeout); #endif /* GD32F4XX_FMC_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h index 3896b98..39a8df6 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h @@ -1,14 +1,12 @@ /*! \file gd32f4xx_fwdgt.h \brief definitions for the FWDGT - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -40,7 +38,7 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* FWDGT definitions */ -#define FWDGT FWDGT_BASE +#define FWDGT FWDGT_BASE /*!< FWDGT base address */ /* registers definitions */ #define FWDGT_CTL REG32((FWDGT) + 0x00U) /*!< FWDGT control register */ @@ -87,6 +85,9 @@ OF SUCH DAMAGE. #define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< FWDGT prescaler divider value update flag */ #define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< FWDGT counter reload value update flag */ +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + /* function declarations */ /* enable write access to FWDGT_PSC and FWDGT_RLD */ void fwdgt_write_enable(void); @@ -95,6 +96,10 @@ void fwdgt_write_disable(void); /* start the free watchdog timer counter */ void fwdgt_enable(void); +/* configure the free watchdog timer counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the free watchdog timer counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value); /* reload the counter of FWDGT */ void fwdgt_counter_reload(void); /* configure counter reload value, and prescaler divider value */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h index 6a363da..2d883b7 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h @@ -1,14 +1,12 @@ /*! \file gd32f4xx_gpio.h \brief definitions for the GPIO - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -57,7 +55,7 @@ OF SUCH DAMAGE. #define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */ #define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ #define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ -#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operate register */ #define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ #define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ #define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ @@ -156,22 +154,22 @@ OF SUCH DAMAGE. #define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ /* GPIO_OCTL */ -#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ -#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ -#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ -#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ -#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ -#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ -#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ -#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ -#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ -#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ -#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ -#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ -#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ -#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ -#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ -#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output control bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output control bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output control bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output control bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output control bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output control bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output control bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output control bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output control bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output control bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output control bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output control bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output control bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output control bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output control bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output control bit */ /* GPIO_BOP */ #define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ @@ -224,7 +222,7 @@ OF SUCH DAMAGE. #define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ #define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ #define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ -#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin lock sequence key */ /* GPIO_AFSEL0 */ #define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ @@ -344,7 +342,7 @@ typedef FlagStatus bit_status; #define GPIO_OSPEED_2MHZ GPIO_OSPEED_LEVEL0 /*!< output max speed 2MHz */ #define GPIO_OSPEED_25MHZ GPIO_OSPEED_LEVEL1 /*!< output max speed 25MHz */ #define GPIO_OSPEED_50MHZ GPIO_OSPEED_LEVEL2 /*!< output max speed 50MHz */ -#define GPIO_OSPEED_200MHZ GPIO_OSPEED_LEVEL3 /*!< output max speed 200MHz */ +#define GPIO_OSPEED_MAX GPIO_OSPEED_LEVEL3 /*!< GPIO very high output speed, max speed more than 50MHz */ /* GPIO alternate function values */ #define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h index bcb6843..8803e9a 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h @@ -1,326 +1,313 @@ /*! \file gd32f4xx_i2c.h \brief definitions for the I2C - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2019-04-16, V2.0.1, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 GD32F4XX_I2C_H #define GD32F4XX_I2C_H #include "gd32f4xx.h" /* I2Cx(x=0,1,2) definitions */ -#define I2C0 I2C_BASE /*!< I2C0 base address */ -#define I2C1 (I2C_BASE+0x400U) /*!< I2C1 base address */ -#define I2C2 (I2C_BASE+0x800U) /*!< I2C2 base address */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE + 0x00000400U) /*!< I2C1 base address */ +#define I2C2 (I2C_BASE + 0x00000800U) /*!< I2C2 base address */ /* registers definitions */ -#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ -#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ -#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0 */ -#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register 1 */ -#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ -#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ -#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ -#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ -#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ -#define I2C_FCTL(i2cx) REG32((i2cx) + 0x24U) /*!< I2C filter control register */ -#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00000000U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x00000004U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x00000008U) /*!< I2C slave address register 0 */ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0000000CU) /*!< I2C slave address register 1 */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x00000010U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x00000014U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x00000018U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x0000001CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x00000020U) /*!< I2C rise time register */ +#define I2C_FCTL(i2cx) REG32((i2cx) + 0x00000024U) /*!< I2C filter control register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x00000080U) /*!< I2C SAM control and status register */ /* bits definitions */ /* I2Cx_CTL0 */ -#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ -#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ -#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ -#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ -#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ -#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ -#define I2C_CTL0_SS BIT(7) /*!< clock stretching disable (slave mode) */ -#define I2C_CTL0_START BIT(8) /*!< start generation */ -#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ -#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ -#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ -#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ -#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ -#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_SS BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ /* I2Cx_CTL1 */ -#define I2C_CTL1_I2CCLK BITS(0,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ -#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt enable */ -#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ -#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ -#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ -#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ +#define I2C_CTL1_I2CCLK BITS(0,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt enable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ /* I2Cx_SADDR0 */ -#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ -#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ -#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ -#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ /* I2Cx_SADDR1 */ -#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ -#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ /* I2Cx_DATA */ -#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ /* I2Cx_STAT0 */ -#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ -#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ -#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ -#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ -#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ -#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ -#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ -#define I2C_STAT0_BERR BIT(8) /*!< bus error */ -#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ -#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ -#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ -#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ -#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ -#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ /* I2Cx_STAT1 */ -#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ -#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ -#define I2C_STAT1_TR BIT(2) /*!< transmitter/receiver */ -#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ -#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ -#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ -#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ -#define I2C_STAT1_PECV BITS(8,15) /*!< packet error checking value */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TR BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_PECV BITS(8,15) /*!< packet error checking value */ /* I2Cx_CKCFG */ -#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ -#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ -#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ /* I2Cx_RT */ -#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ /* I2Cx_FCTL */ -#define I2C_FCTL_DF BITS(0,3) /*!< digital noise filter */ -#define I2C_FCTL_AFD BIT(4) /*!< analog noise filter disable */ +#define I2C_FCTL_DF BITS(0,3) /*!< digital noise filter */ +#define I2C_FCTL_AFD BIT(4) /*!< analog noise filter disable */ /* I2Cx_SAMCS */ -#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ -#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ -#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ -#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ -#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ -#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ -#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ -#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ -#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag, cleared by software write 0 */ -#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag, cleared by software write 0 */ -#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag, cleared by software write 0 */ -#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag, cleared by software write 0 */ - -/* constants definitions */ - -/* the digital noise filter can filter spikes's length */ -typedef enum { - I2C_DF_DISABLE, /*!< disable digital noise filter */ - I2C_DF_1PCLK, /*!< enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 */ - I2C_DF_2PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 */ - I2C_DF_3PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 */ - I2C_DF_4PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 */ - I2C_DF_5PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 */ - I2C_DF_6PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 */ - I2C_DF_7PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 */ - I2C_DF_8PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 */ - I2C_DF_9PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 */ - I2C_DF_10PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 */ - I2C_DF_11PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 */ - I2C_DF_12PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 */ - I2C_DF_13PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 */ - I2C_DF_14PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 */ - I2C_DF_15PCLKS /*!< enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 */ -}i2c_digital_filter_enum; +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag */ /* constants definitions */ /* define the I2C bit position and its register index offset */ #define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) -#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) -#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) #define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ - | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) #define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) -#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) /* register offset */ -#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ -#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */ -#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */ -#define I2C_SAMCS_REG_OFFSET 0x80U /*!< SAMCS register offset */ +#define I2C_CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET ((uint32_t)0x00000014U) /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET ((uint32_t)0x00000018U) /*!< STAT1 register offset */ +#define I2C_SAMCS_REG_OFFSET ((uint32_t)0x00000080U) /*!< SAMCS register offset */ /* I2C flags */ -typedef enum -{ +typedef enum { /* flags in STAT0 register */ - I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */ - I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */ - I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ - I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */ - I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */ - I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving */ - I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */ - I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ - I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */ - I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */ - I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */ - I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */ - I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */ - I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */ + I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */ + I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */ + I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */ + I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */ + I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not empty during receiving */ + I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */ + I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ + I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */ + I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */ + I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */ + I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */ + I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */ + I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */ /* flags in STAT1 register */ - I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */ - I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */ - I2C_FLAG_TRS = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */ - I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */ - I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */ - I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */ - I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */ + I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */ + I2C_FLAG_TR = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */ + I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */ + I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */ + I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */ + I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ /* flags in SAMCS register */ - I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */ - I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */ - I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */ - I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */ -}i2c_flag_enum; + I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */ + I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */ + I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */ + I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */ +} i2c_flag_enum; /* I2C interrupt flags */ -typedef enum -{ +typedef enum { /* interrupt flags in CTL1 register */ I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode interrupt flag */ I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ - I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes interrupt flag */ I2C_INT_FLAG_ADD10SEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode interrupt flag */ I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode interrupt flag */ I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving interrupt flag */ - I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */ + I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */ I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode interrupt flag */ I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error interrupt flag */ I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode interrupt flag */ I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data interrupt flag */ I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode interrupt flag */ - I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus Alert status interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status interrupt flag */ /* interrupt flags in SAMCS register */ - I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */ - I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */ + I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */ + I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */ I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall interrupt flag */ - I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */ -}i2c_interrupt_flag_enum; + I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */ +} i2c_interrupt_flag_enum; -/* I2C interrupt enable or disable */ -typedef enum -{ +/* I2C interrupt */ +typedef enum { /* interrupt in CTL1 register */ - I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt enable */ - I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt enable */ - I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt enable */ + I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt */ + I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt */ + I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt */ /* interrupt in SAMCS register */ - I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt enable */ - I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt enable */ - I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt enable */ - I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt enable */ -}i2c_interrupt_enum; + I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt */ + I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt */ + I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt */ + I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt */ +} i2c_interrupt_enum; + +/* the digital noise filter can filter spikes's length */ +typedef enum { + I2C_DF_DISABLE = 0, /*!< disable digital noise filter */ + I2C_DF_1PCLK, /*!< enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 */ + I2C_DF_2PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 */ + I2C_DF_3PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 */ + I2C_DF_4PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 */ + I2C_DF_5PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 */ + I2C_DF_6PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 */ + I2C_DF_7PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 */ + I2C_DF_8PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 */ + I2C_DF_9PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 */ + I2C_DF_10PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 */ + I2C_DF_11PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 */ + I2C_DF_12PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 */ + I2C_DF_13PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 */ + I2C_DF_14PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 */ + I2C_DF_15PCLKS /*!< enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 */ +} i2c_digital_filter_enum; /* SMBus/I2C mode switch and SMBus type selection */ -#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ -#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ /* SMBus/I2C mode switch and SMBus type selection */ -#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ -#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ /* I2C transfer direction */ -#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ -#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ /* whether or not to send an ACK */ -#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ -#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE I2C_CTL0_ACKEN /*!< ACK will be sent */ /* I2C POAP position*/ -#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ -#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ - -/* I2C dual-address mode switch */ -#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */ -#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< dual-address mode enabled */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ +#define I2C_ACKPOS_NEXT I2C_CTL0_POAP /*!< ACKEN bit decides whether or not to send ACK for the next byte */ /* whether or not to stretch SCL low */ -#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< SCL stretching is enabled */ -#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_SS /*!< SCL stretching is disabled */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< enable SCL stretching */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_SS /*!< disable SCL stretching */ /* whether or not to response to a general call */ -#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ -#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ /* software reset I2C */ -#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ -#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ /* I2C DMA mode configure */ /* DMA mode switch */ -#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ -#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< disable DMA mode */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< enable DMA mode */ /* flag indicating DMA last transfer */ -#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ -#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ /* I2C PEC configure */ /* PEC enable */ -#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ -#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ /* PEC transfer */ -#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ -#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC value */ /* I2C SMBus configure */ /* issue or not alert through SMBA pin */ -#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ -#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ /* ARP protocol in SMBus switch */ -#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP is enabled */ -#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP is disabled */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< disable ARP */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< enable ARP */ /* transmit I2C data */ #define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) @@ -329,21 +316,24 @@ typedef enum #define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) /* I2C duty cycle in fast mode */ -#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< I2C fast mode Tlow/Thigh = 2 */ -#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< I2C fast mode Tlow/Thigh = 16/9 */ +#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< T_low/T_high = 2 in fast mode */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< T_low/T_high = 16/9 in fast mode */ /* address mode for the I2C slave */ -#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ -#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address format is 7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address format is 10 bits */ /* function declarations */ +/* initialization functions */ /* reset I2C */ void i2c_deinit(uint32_t i2c_periph); /* configure I2C clock */ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); /* configure I2C address */ void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); -/* SMBus type selection */ + +/* application function declarations */ +/* select SMBus type */ void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); /* whether or not to send an ACK */ void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); @@ -359,7 +349,6 @@ void i2c_dualaddr_disable(uint32_t i2c_periph); void i2c_enable(uint32_t i2c_periph); /* disable I2C */ void i2c_disable(uint32_t i2c_periph); - /* generate a START condition on I2C bus */ void i2c_start_on_bus(uint32_t i2c_periph); /* generate a STOP condition on I2C bus */ @@ -368,35 +357,32 @@ void i2c_stop_on_bus(uint32_t i2c_periph); void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); /* I2C receive data function */ uint8_t i2c_data_receive(uint32_t i2c_periph); -/* enable I2C DMA mode */ -void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* configure I2C DMA mode */ +void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate); /* configure whether next DMA EOT is DMA last transfer or not */ void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast); /* whether to stretch SCL low when data is not ready in slave mode */ void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara); /* whether or not to response to a general call */ void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); -/* software reset I2C */ +/* configure software reset of I2C */ void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); - -/* I2C PEC calculation on or off */ -void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); -/* I2C whether to transfer PEC value */ -void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); -/* packet error checking value */ +/* configure I2C PEC calculation */ +void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate); +/* configure whether to transfer PEC value */ +void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara); +/* get packet error checking value */ uint8_t i2c_pec_value_get(uint32_t i2c_periph); -/* I2C issue alert through SMBA pin */ -void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); -/* I2C ARP protocol in SMBus switch */ -void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); - -/* I2C analog noise filter disable */ +/* configure I2C alert through SMBA pin */ +void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara); +/* configure I2C ARP protocol in SMBus */ +void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate); +/* disable analog noise filter */ void i2c_analog_noise_filter_disable(uint32_t i2c_periph); -/* I2C analog noise filter enable */ +/* enable analog noise filter */ void i2c_analog_noise_filter_enable(uint32_t i2c_periph); -/* digital noise filter */ -void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara); - +/* configure digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara); /* enable SAM_V interface */ void i2c_sam_enable(uint32_t i2c_periph); /* disable SAM_V interface */ @@ -406,17 +392,18 @@ void i2c_sam_timeout_enable(uint32_t i2c_periph); /* disable SAM_V interface timeout detect */ void i2c_sam_timeout_disable(uint32_t i2c_periph); -/* check I2C flag is set or not */ +/* interrupt & flag functions */ +/* get I2C flag status */ FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag); -/* clear I2C flag */ +/* clear I2C flag status */ void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag); /* enable I2C interrupt */ void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); /* disable I2C interrupt */ void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); -/* check I2C interrupt flag */ +/* get I2C interrupt flag status */ FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); -/* clear I2C interrupt flag */ +/* clear I2C interrupt flag status */ void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); #endif /* GD32F4XX_I2C_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h index 84cceeb..8641378 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h @@ -1,36 +1,34 @@ /*! \file gd32f4xx_ipa.h \brief definitions for the IPA - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -40,30 +38,30 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* TLI definitions */ -#define IPA IPA_BASE /*!< IPA base address */ +#define IPA IPA_BASE /*!< IPA base address */ /* bits definitions */ /* registers definitions */ -#define IPA_CTL REG32(IPA + 0x00U) /*!< IPA control register */ -#define IPA_INTF REG32(IPA + 0x04U) /*!< IPA interrupt flag register */ -#define IPA_INTC REG32(IPA + 0x08U) /*!< IPA interrupt flag clear register */ -#define IPA_FMADDR REG32(IPA + 0x0CU) /*!< IPA foreground memory base address register */ -#define IPA_FLOFF REG32(IPA + 0x10U) /*!< IPA foreground line offset register */ -#define IPA_BMADDR REG32(IPA + 0x14U) /*!< IPA background memory base address register */ -#define IPA_BLOFF REG32(IPA + 0x18U) /*!< IPA background line offset register */ -#define IPA_FPCTL REG32(IPA + 0x1CU) /*!< IPA foreground pixel control register */ -#define IPA_FPV REG32(IPA + 0x20U) /*!< IPA foreground pixel value register */ -#define IPA_BPCTL REG32(IPA + 0x24U) /*!< IPA background pixel control register */ -#define IPA_BPV REG32(IPA + 0x28U) /*!< IPA background pixel value register */ -#define IPA_FLMADDR REG32(IPA + 0x2CU) /*!< IPA foreground LUT memory base address register */ -#define IPA_BLMADDR REG32(IPA + 0x30U) /*!< IPA background LUT memory base address register */ -#define IPA_DPCTL REG32(IPA + 0x34U) /*!< IPA destination pixel control register */ -#define IPA_DPV REG32(IPA + 0x38U) /*!< IPA destination pixel value register */ -#define IPA_DMADDR REG32(IPA + 0x3CU) /*!< IPA destination memory base address register */ -#define IPA_DLOFF REG32(IPA + 0x40U) /*!< IPA destination line offset register */ -#define IPA_IMS REG32(IPA + 0x44U) /*!< IPA image size register */ -#define IPA_LM REG32(IPA + 0x48U) /*!< IPA line mark register */ -#define IPA_ITCTL REG32(IPA + 0x4CU) /*!< IPA inter-timer control register */ +#define IPA_CTL REG32(IPA + 0x00000000U) /*!< IPA control register */ +#define IPA_INTF REG32(IPA + 0x00000004U) /*!< IPA interrupt flag register */ +#define IPA_INTC REG32(IPA + 0x00000008U) /*!< IPA interrupt flag clear register */ +#define IPA_FMADDR REG32(IPA + 0x0000000CU) /*!< IPA foreground memory base address register */ +#define IPA_FLOFF REG32(IPA + 0x00000010U) /*!< IPA foreground line offset register */ +#define IPA_BMADDR REG32(IPA + 0x00000014U) /*!< IPA background memory base address register */ +#define IPA_BLOFF REG32(IPA + 0x00000018U) /*!< IPA background line offset register */ +#define IPA_FPCTL REG32(IPA + 0x0000001CU) /*!< IPA foreground pixel control register */ +#define IPA_FPV REG32(IPA + 0x00000020U) /*!< IPA foreground pixel value register */ +#define IPA_BPCTL REG32(IPA + 0x00000024U) /*!< IPA background pixel control register */ +#define IPA_BPV REG32(IPA + 0x00000028U) /*!< IPA background pixel value register */ +#define IPA_FLMADDR REG32(IPA + 0x0000002CU) /*!< IPA foreground LUT memory base address register */ +#define IPA_BLMADDR REG32(IPA + 0x00000030U) /*!< IPA background LUT memory base address register */ +#define IPA_DPCTL REG32(IPA + 0x00000034U) /*!< IPA destination pixel control register */ +#define IPA_DPV REG32(IPA + 0x00000038U) /*!< IPA destination pixel value register */ +#define IPA_DMADDR REG32(IPA + 0x0000003CU) /*!< IPA destination memory base address register */ +#define IPA_DLOFF REG32(IPA + 0x00000040U) /*!< IPA destination line offset register */ +#define IPA_IMS REG32(IPA + 0x00000044U) /*!< IPA image size register */ +#define IPA_LM REG32(IPA + 0x00000048U) /*!< IPA line mark register */ +#define IPA_ITCTL REG32(IPA + 0x0000004CU) /*!< IPA inter-timer control register */ /* IPA_CTL */ #define IPA_CTL_TEN BIT(0) /*!< transfer enable */ @@ -189,8 +187,7 @@ OF SUCH DAMAGE. /* constants definitions */ /* IPA foreground parameter struct definitions */ -typedef struct -{ +typedef struct { uint32_t foreground_memaddr; /*!< foreground memory base address */ uint32_t foreground_lineoff; /*!< foreground line offset */ uint32_t foreground_prealpha; /*!< foreground pre-defined alpha value */ @@ -199,11 +196,10 @@ typedef struct uint32_t foreground_prered; /*!< foreground pre-defined red value */ uint32_t foreground_pregreen; /*!< foreground pre-defined green value */ uint32_t foreground_preblue; /*!< foreground pre-defined blue value */ -}ipa_foreground_parameter_struct; +} ipa_foreground_parameter_struct; /* IPA background parameter struct definitions */ -typedef struct -{ +typedef struct { uint32_t background_memaddr; /*!< background memory base address */ uint32_t background_lineoff; /*!< background line offset */ uint32_t background_prealpha; /*!< background pre-defined alpha value */ @@ -212,11 +208,10 @@ typedef struct uint32_t background_prered; /*!< background pre-defined red value */ uint32_t background_pregreen; /*!< background pre-defined green value */ uint32_t background_preblue; /*!< background pre-defined blue value */ -}ipa_background_parameter_struct; +} ipa_background_parameter_struct; /* IPA destination parameter struct definitions */ -typedef struct -{ +typedef struct { uint32_t destination_memaddr; /*!< destination memory base address */ uint32_t destination_lineoff; /*!< destination line offset */ uint32_t destination_prealpha; /*!< destination pre-defined alpha value */ @@ -226,11 +221,10 @@ typedef struct uint32_t destination_preblue; /*!< destination pre-defined blue value */ uint32_t image_width; /*!< width of the image to be processed */ uint32_t image_height; /*!< height of the image to be processed */ -}ipa_destination_parameter_struct; +} ipa_destination_parameter_struct; /* destination pixel format */ -typedef enum -{ +typedef enum { IPA_DPF_ARGB8888, /*!< destination pixel format ARGB8888 */ IPA_DPF_RGB888, /*!< destination pixel format RGB888 */ IPA_DPF_RGB565, /*!< destination pixel format RGB565 */ @@ -339,21 +333,21 @@ void ipa_background_lut_loading_enable(void); void ipa_pixel_format_convert_mode_set(uint32_t pfcm); /* structure initialization, foreground, background, destination and LUT initialization */ -/* initialize the structure of IPA foreground parameter struct with the default values, it is +/* initialize the structure of IPA foreground parameter struct with the default values, it is suggested that call this function after an ipa_foreground_parameter_struct structure is defined */ -void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct* foreground_struct); +void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct *foreground_struct); /* initialize foreground parameters */ -void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct); -/* initialize the structure of IPA background parameter struct with the default values, it is +void ipa_foreground_init(ipa_foreground_parameter_struct *foreground_struct); +/* initialize the structure of IPA background parameter struct with the default values, it is suggested that call this function after an ipa_background_parameter_struct structure is defined */ -void ipa_background_struct_para_init(ipa_background_parameter_struct* background_struct); +void ipa_background_struct_para_init(ipa_background_parameter_struct *background_struct); /* initialize background parameters */ -void ipa_background_init(ipa_background_parameter_struct* background_struct); -/* initialize the structure of IPA destination parameter struct with the default values, it is +void ipa_background_init(ipa_background_parameter_struct *background_struct); +/* initialize the structure of IPA destination parameter struct with the default values, it is suggested that call this function after an ipa_destination_parameter_struct structure is defined */ -void ipa_destination_struct_para_init(ipa_destination_parameter_struct* destination_struct); +void ipa_destination_struct_para_init(ipa_destination_parameter_struct *destination_struct); /* initialize destination parameters */ -void ipa_destination_init(ipa_destination_parameter_struct* destination_struct); +void ipa_destination_init(ipa_destination_parameter_struct *destination_struct); /* initialize IPA foreground LUT parameters */ void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_lut_addr); /* initialize IPA background LUT parameters */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h index 44897a2..4189fa4 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h @@ -2,13 +2,11 @@ \file gd32f4xx_iref.h \brief definitions for the IREF - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -167,7 +165,7 @@ OF SUCH DAMAGE. #define IREF_SINK_CURRENT IREF_CURRENT(1) /*!< IREF sink current */ /* function declarations */ -/* deinit IREF */ +/* deinitialize IREF */ void iref_deinit(void); /* enable IREF */ void iref_enable(void); diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h index e618af4..1a672d5 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h @@ -1,14 +1,11 @@ /*! \file gd32f4xx_misc.h \brief definitions for the MISC - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -41,8 +38,8 @@ OF SUCH DAMAGE. /* constants definitions */ /* set the RAM and FLASH base address */ -#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ -#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ /* set the NVIC vector table offset mask */ #define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) @@ -51,24 +48,24 @@ OF SUCH DAMAGE. #define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) /* priority group - define the pre-emption priority and the subpriority */ -#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ -#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ -#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ -#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ -#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */ /* choose the method to enter or exit the lowpower mode */ -#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ -#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ -#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ #define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT #define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP #define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND /* choose the systick clock source */ -#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ -#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ /* function declarations */ /* set the priority group */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h index b80748c..4f5bf28 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h @@ -2,13 +2,11 @@ \file gd32f4xx_pmu.h \brief definitions for the PMU - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -41,159 +39,165 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* PMU definitions */ -#define PMU PMU_BASE /*!< PMU base address */ +#define PMU PMU_BASE /*!< PMU base address */ /* registers definitions */ -#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ -#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ +#define PMU_CTL REG32((PMU) + 0x00000000U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x00000004U) /*!< PMU control and status register */ /* bits definitions */ /* PMU_CTL */ -#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ -#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ -#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ -#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ -#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ -#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ -#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ -#define PMU_CTL_LDLP BIT(10) /*!< low-driver mode when use low power LDO */ -#define PMU_CTL_LDNP BIT(11) /*!< low-driver mode when use normal power LDO */ -#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ -#define PMU_CTL_HDEN BIT(16) /*!< high-driver mode enable */ -#define PMU_CTL_HDS BIT(17) /*!< high-driver mode switch */ -#define PMU_CTL_LDEN BITS(18,19) /*!< low-driver mode enable in deep-sleep mode */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_LDLP BIT(10) /*!< low-driver mode when use low power LDO */ +#define PMU_CTL_LDNP BIT(11) /*!< low-driver mode when use normal power LDO */ +#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ +#define PMU_CTL_HDEN BIT(16) /*!< high-driver mode enable */ +#define PMU_CTL_HDS BIT(17) /*!< high-driver mode switch */ +#define PMU_CTL_LDEN BITS(18,19) /*!< low-driver mode enable in deep-sleep mode */ /* PMU_CS */ -#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ -#define PMU_CS_STBF BIT(1) /*!< standby flag */ -#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ -#define PMU_CS_BLDORF BIT(3) /*!< backup SRAM LDO ready flag */ -#define PMU_CS_WUPEN BIT(8) /*!< wakeup pin enable */ -#define PMU_CS_BLDOON BIT(9) /*!< backup SRAM LDO on */ -#define PMU_CS_LDOVSRF BIT(14) /*!< LDO voltage select ready flag */ -#define PMU_CS_HDRF BIT(16) /*!< high-driver ready flag */ -#define PMU_CS_HDSRF BIT(17) /*!< high-driver switch ready flag */ -#define PMU_CS_LDRF BITS(18,19) /*!< Low-driver mode ready flag */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_BLDORF BIT(3) /*!< backup SRAM LDO ready flag */ +#define PMU_CS_WUPEN BIT(8) /*!< wakeup pin enable */ +#define PMU_CS_BLDOON BIT(9) /*!< backup SRAM LDO on */ +#define PMU_CS_LDOVSRF BIT(14) /*!< LDO voltage select ready flag */ +#define PMU_CS_HDRF BIT(16) /*!< high-driver ready flag */ +#define PMU_CS_HDSRF BIT(17) /*!< high-driver switch ready flag */ +#define PMU_CS_LDRF BITS(18,19) /*!< low-driver mode ready flag */ /* constants definitions */ +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deep-sleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deep-sleep mode */ + /* PMU low voltage detector threshold definitions */ #define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) -#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.1V */ -#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ -#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ -#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.6V */ -#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */ -#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */ -#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */ -#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */ +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.1V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */ + +/* PMU low-driver mode when use low power LDO */ +#define CTL_LDLP(regval) (BIT(10)&((uint32_t)(regval)<<10)) +#define PMU_NORMALDR_LOWPWR CTL_LDLP(0) /*!< normal driver when use low power LDO */ +#define PMU_LOWDR_LOWPWR CTL_LDLP(1) /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */ + +/* PMU low-driver mode when use normal power LDO */ +#define CTL_LDNP(regval) (BIT(11)&((uint32_t)(regval)<<11)) +#define PMU_NORMALDR_NORMALPWR CTL_LDNP(0) /*!< normal driver when use normal power LDO */ +#define PMU_LOWDR_NORMALPWR CTL_LDNP(1) /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */ /* PMU LDO output voltage select definitions */ #define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14)) -#define PMU_LDOVS_LOW CTL_LDOVS(1) /*!< LDO output voltage low mode */ -#define PMU_LDOVS_MID CTL_LDOVS(2) /*!< LDO output voltage mid mode */ -#define PMU_LDOVS_HIGH CTL_LDOVS(3) /*!< LDO output voltage high mode */ +#define PMU_LDOVS_LOW CTL_LDOVS(1) /*!< LDO output voltage low mode */ +#define PMU_LDOVS_MID CTL_LDOVS(2) /*!< LDO output voltage mid mode */ +#define PMU_LDOVS_HIGH CTL_LDOVS(3) /*!< LDO output voltage high mode */ -/* PMU low-driver mode enable in deep-sleep mode */ -#define CTL_LDEN(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) -#define PMU_LOWDRIVER_DISABLE CTL_LDEN(0) /*!< low-driver mode disable in deep-sleep mode */ -#define PMU_LOWDRIVER_ENABLE CTL_LDEN(3) /*!< low-driver mode enable in deep-sleep mode */ /* PMU high-driver mode switch */ #define CTL_HDS(regval) (BIT(17)&((uint32_t)(regval)<<17)) -#define PMU_HIGHDR_SWITCH_NONE CTL_HDS(0) /*!< no high-driver mode switch */ -#define PMU_HIGHDR_SWITCH_EN CTL_HDS(1) /*!< high-driver mode switch */ +#define PMU_HIGHDR_SWITCH_NONE CTL_HDS(0) /*!< no high-driver mode switch */ +#define PMU_HIGHDR_SWITCH_EN CTL_HDS(1) /*!< high-driver mode switch */ -/* PMU low-driver mode when use low power LDO */ -#define CTL_LDLP(regval) (BIT(10)&((uint32_t)(regval)<<10)) -#define PMU_NORMALDR_LOWPWR CTL_LDLP(0) /*!< normal driver when use low power LDO */ -#define PMU_LOWDR_LOWPWR CTL_LDLP(1) /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */ +/* PMU low-driver mode enable in deep-sleep mode */ +#define CTL_LDEN(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) +#define PMU_LOWDRIVER_DISABLE CTL_LDEN(0) /*!< low-driver mode disable in deep-sleep mode */ +#define PMU_LOWDRIVER_ENABLE CTL_LDEN(3) /*!< low-driver mode enable in deep-sleep mode */ -/* PMU low-driver mode when use normal power LDO */ -#define CTL_LDNP(regval) (BIT(11)&((uint32_t)(regval)<<11)) -#define PMU_NORMALDR_NORMALPWR CTL_LDNP(0) /*!< normal driver when use normal power LDO */ -#define PMU_LOWDR_NORMALPWR CTL_LDNP(1) /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */ +/* PMU backup SRAM LDO on or off */ +#define CS_BLDOON(regval) (BIT(9)&((uint32_t)(regval)<<9)) +#define PMU_BLDOON_OFF CS_BLDOON(0) /*!< backup SRAM LDO off */ +#define PMU_BLDOON_ON CS_BLDOON(1) /*!< the backup SRAM LDO on */ /* PMU low power mode ready flag definitions */ #define CS_LDRF(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) -#define PMU_LDRF_NORMAL CS_LDRF(0) /*!< normal driver in deep-sleep mode */ -#define PMU_LDRF_LOWDRIVER CS_LDRF(3) /*!< low-driver mode in deep-sleep mode */ - -/* PMU backup SRAM LDO on or off */ -#define CS_BLDOON(regval) (BIT(9)&((uint32_t)(regval)<<9)) -#define PMU_BLDOON_OFF CS_BLDOON(0) /*!< backup SRAM LDO off */ -#define PMU_BLDOON_ON CS_BLDOON(1) /*!< the backup SRAM LDO on */ +#define PMU_LDRF_NORMAL CS_LDRF(0) /*!< normal driver in deep-sleep mode */ +#define PMU_LDRF_LOWDRIVER CS_LDRF(3) /*!< low-driver mode in deep-sleep mode */ /* PMU flag definitions */ -#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ -#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ -#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ -#define PMU_FLAG_BLDORF PMU_CS_BLDORF /*!< backup SRAM LDO ready flag */ -#define PMU_FLAG_LDOVSRF PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */ -#define PMU_FLAG_HDRF PMU_CS_HDRF /*!< high-driver ready flag */ -#define PMU_FLAG_HDSRF PMU_CS_HDSRF /*!< high-driver switch ready flag */ -#define PMU_FLAG_LDRF PMU_CS_LDRF /*!< low-driver mode ready flag */ - -/* PMU ldo definitions */ -#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deepsleep mode */ -#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ +#define PMU_FLAG_BLDORF PMU_CS_BLDORF /*!< backup SRAM LDO ready flag */ +#define PMU_FLAG_LDOVSRF PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */ +#define PMU_FLAG_HDRF PMU_CS_HDRF /*!< high-driver ready flag */ +#define PMU_FLAG_HDSRF PMU_CS_HDSRF /*!< high-driver switch ready flag */ +#define PMU_FLAG_LDRF PMU_CS_LDRF /*!< low-driver mode ready flag */ /* PMU flag reset definitions */ -#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ -#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ /* PMU command constants definitions */ -#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ -#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ /* function declarations */ -/* reset PMU register */ +/* reset PMU registers */ void pmu_deinit(void); +/* LVD functions */ /* select low voltage detector threshold */ void pmu_lvd_select(uint32_t lvdt_n); -/* LDO output voltage select */ -void pmu_ldo_output_select(uint32_t ldo_output); -/* PMU lvd disable */ +/* disable PMU lvd */ void pmu_lvd_disable(void); -/* functions of low-driver mode and high-driver mode in deep-sleep mode */ -/* high-driver mode switch */ -void pmu_highdriver_switch_select(uint32_t highdr_switch); -/* high-driver mode enable */ +/* LDO functions */ +/* select LDO output voltage */ +void pmu_ldo_output_select(uint32_t ldo_output); + +/* functions of low-driver mode and high-driver mode */ +/* enable high-driver mode */ void pmu_highdriver_mode_enable(void); -/* high-driver mode disable */ +/* disable high-driver mode */ void pmu_highdriver_mode_disable(void); -/* low-driver mode enable in deep-sleep mode */ -void pmu_low_driver_mode_enable(uint32_t lowdr_mode); -/* in deep-sleep mode, low-driver mode when use low power LDO */ -void pmu_lowdriver_lowpower_config(uint32_t mode); -/* in deep-sleep mode, low-driver mode when use normal power LDO */ -void pmu_lowdriver_normalpower_config(uint32_t mode); +/* switch high-driver mode */ +void pmu_highdriver_switch_select(uint32_t highdr_switch); +/* enable low-driver mode in deep-sleep */ +void pmu_lowdriver_mode_enable(void); +/* disable low-driver mode in deep-sleep */ +void pmu_lowdriver_mode_disable(void); +/* in deep-sleep mode, driver mode when use low power LDO */ +void pmu_lowpower_driver_config(uint32_t mode); +/* in deep-sleep mode, driver mode when use normal power LDO */ +void pmu_normalpower_driver_config(uint32_t mode); /* set PMU mode */ -/* PMU work at sleep mode */ +/* PMU work in sleep mode */ void pmu_to_sleepmode(uint8_t sleepmodecmd); -/* PMU work at deepsleep mode */ -void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd); -/* PMU work at standby mode */ -void pmu_to_standbymode(uint8_t standbymodecmd); -/* PMU wakeup pin enable */ +/* PMU work in deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd); +/* PMU work in standby mode */ +void pmu_to_standbymode(void); +/* enable PMU wakeup pin */ void pmu_wakeup_pin_enable(void); -/* PMU wakeup pin disable */ +/* disable PMU wakeup pin */ void pmu_wakeup_pin_disable(void); /* backup related functions */ /* backup SRAM LDO on */ void pmu_backup_ldo_config(uint32_t bkp_ldo); -/* backup domain write enable */ +/* enable write access to the registers in backup domain */ void pmu_backup_write_enable(void); -/* backup domain write disable */ +/* disable write access to the registers in backup domain */ void pmu_backup_write_disable(void); /* flag functions */ -/* reset flag bit */ -void pmu_flag_reset(uint32_t flag_reset); -/* get flag status */ -FlagStatus pmu_flag_get(uint32_t pmu_flag); +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag); #endif /* GD32F4XX_PMU_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h index 8aea0fc..dfea500 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h @@ -2,13 +2,11 @@ \file gd32f4xx_rcu.h \brief definitions for the RCU - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -397,13 +395,11 @@ OF SUCH DAMAGE. /* RCU_PLLI2S */ #define RCU_PLLI2S_PLLI2SN BITS(6,14) /*!< the PLLI2S VCO clock multi factor */ -#define RCU_PLLI2S_PLLI2SQ BITS(24,27) /*!< the PLLI2S Q output frequency division factor from PLLI2S VCO clock */ #define RCU_PLLI2S_PLLI2SR BITS(28,30) /*!< the PLLI2S R output frequency division factor from PLLI2S VCO clock */ /* RCU_PLLSAI */ #define RCU_PLLSAI_PLLSAIN BITS(6,14) /*!< the PLLSAI VCO clock multi factor */ #define RCU_PLLSAI_PLLSAIP BITS(16,17) /*!< the PLLSAI P output frequency division factor from PLLSAI VCO clock */ -#define RCU_PLLSAI_PLLSAIQ BITS(24,27) /*!< the PLLSAI Q output frequency division factor from PLLSAI VCO clock */ #define RCU_PLLSAI_PLLSAIR BITS(28,30) /*!< the PLLSAI R output frequency division factor from PLLSAI VCO clock */ /* RCU_CFG1 */ @@ -1068,13 +1064,14 @@ typedef enum /* Deep-sleep mode voltage */ #define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) -#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ -#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ -#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ -#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0 DSV_DSLPVS(0) /*!< core voltage is default value in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1 DSV_DSLPVS(1) /*!< core voltage is (default value-0.1)V in deep-sleep mode(customers are not recommended to use it)*/ +#define RCU_DEEPSLEEP_V_2 DSV_DSLPVS(2) /*!< core voltage is (default value-0.2)V in deep-sleep mode(customers are not recommended to use it)*/ +#define RCU_DEEPSLEEP_V_3 DSV_DSLPVS(3) /*!< core voltage is (default value-0.3)V in deep-sleep mode(customers are not recommended to use it)*/ /* function declarations */ +/* peripherals clock configure functions */ /* deinitialize the RCU */ void rcu_deinit(void); /* enable the peripherals clock */ @@ -1094,6 +1091,7 @@ void rcu_bkp_reset_enable(void); /* disable the BKP reset */ void rcu_bkp_reset_disable(void); +/* system and peripherals clock source, system reset configure functions */ /* configure the system clock source */ void rcu_system_clock_source_config(uint32_t ck_sys); /* get the system clock source */ @@ -1129,20 +1127,7 @@ void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler); /* configure the TLI clock division selection */ void rcu_tli_clock_div_config(uint32_t pllsai_r_div); - -/* get the clock stabilization and periphral reset flags */ -FlagStatus rcu_flag_get(rcu_flag_enum flag); -/* clear the reset flag */ -void rcu_all_reset_flag_clear(void); -/* get the clock stabilization interrupt and ckm flags */ -FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); -/* clear the interrupt flags */ -void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag); -/* enable the stabilization interrupt */ -void rcu_interrupt_enable(rcu_int_enum interrupt); -/* disable the stabilization interrupt */ -void rcu_interrupt_disable(rcu_int_enum interrupt); - +/* LXTAL, IRC8M, PLL and other oscillator configure functions */ /* configure the LXTAL drive capability */ void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); /* wait for oscillator stabilization flags is SET or oscillator startup is timeout */ @@ -1155,11 +1140,6 @@ void rcu_osci_off(rcu_osci_type_enum osci); void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); /* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); -/* enable the HXTAL clock monitor */ -void rcu_hxtal_clock_monitor_enable(void); -/* disable the HXTAL clock monitor */ -void rcu_hxtal_clock_monitor_disable(void); - /* set the IRC16M adjust value */ void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval); /* configure the spread spectrum modulation for the main PLL clock */ @@ -1167,13 +1147,34 @@ void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, /* enable the spread spectrum modulation for the main PLL clock */ void rcu_spread_spectrum_enable(void); /* disable the spread spectrum modulation for the main PLL clock */ -void rcu_spread_spectrum_disable(void); +void rcu_spread_spectrum_disable(void); + +/* clock monitor configure functions */ +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* voltage configure and clock frequency get functions */ /* unlock the voltage key */ void rcu_voltage_key_unlock(void); /* set the deep sleep mode voltage */ void rcu_deepsleep_voltage_set(uint32_t dsvol); - /* get the system clock, bus and peripheral clock frequency */ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); +/* flag & interrupt functions */ +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum interrupt); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum interrupt); + #endif /* GD32F4XX_RCU_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h index 2cc9461..3bf1f64 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h @@ -2,13 +2,11 @@ \file gd32f4xx_rtc.c \brief definitions for the RTC - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -524,7 +522,7 @@ typedef struct #define RTC_AF1_TAMPER0 RTC_TAMP_TP0SEL /*!< RTC_AF1 use for tamper0 */ /* RTC flags */ -#define RTC_FLAG_ALRM0W RTC_STAT_ALRM0WF /*!< alarm0 configuration can be write flag */ +#define RTC_FLAG_ALRM0W RTC_STAT_ALRM0WF /*!< alarm0 configuration can be write flag */ #define RTC_FLAG_ALRM1W RTC_STAT_ALRM1WF /*!< alarm1 configuration can be write flag */ #define RTC_FLAG_WTW RTC_STAT_WTWF /*!< wakeup timer can be write flag */ #define RTC_FLAG_SOP RTC_STAT_SOPF /*!< shift function operation pending flag */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h index d6ee114..ea0ec88 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h @@ -1,36 +1,34 @@ /*! \file gd32f4xx_sdio.h \brief definitions for the SDIO - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -43,24 +41,24 @@ OF SUCH DAMAGE. #define SDIO SDIO_BASE /* registers definitions */ -#define SDIO_PWRCTL REG32(SDIO + 0x00U) /*!< SDIO power control register */ -#define SDIO_CLKCTL REG32(SDIO + 0x04U) /*!< SDIO clock control register */ -#define SDIO_CMDAGMT REG32(SDIO + 0x08U) /*!< SDIO command argument register */ -#define SDIO_CMDCTL REG32(SDIO + 0x0CU) /*!< SDIO command control register */ -#define SDIO_RSPCMDIDX REG32(SDIO + 0x10U) /*!< SDIO command index response register */ -#define SDIO_RESP0 REG32(SDIO + 0x14U) /*!< SDIO response register 0 */ -#define SDIO_RESP1 REG32(SDIO + 0x18U) /*!< SDIO response register 1 */ -#define SDIO_RESP2 REG32(SDIO + 0x1CU) /*!< SDIO response register 2 */ -#define SDIO_RESP3 REG32(SDIO + 0x20U) /*!< SDIO response register 3 */ -#define SDIO_DATATO REG32(SDIO + 0x24U) /*!< SDIO data timeout register */ -#define SDIO_DATALEN REG32(SDIO + 0x28U) /*!< SDIO data length register */ -#define SDIO_DATACTL REG32(SDIO + 0x2CU) /*!< SDIO data control register */ -#define SDIO_DATACNT REG32(SDIO + 0x30U) /*!< SDIO data counter register */ -#define SDIO_STAT REG32(SDIO + 0x34U) /*!< SDIO status register */ -#define SDIO_INTC REG32(SDIO + 0x38U) /*!< SDIO interrupt clear register */ -#define SDIO_INTEN REG32(SDIO + 0x3CU) /*!< SDIO interrupt enable register */ -#define SDIO_FIFOCNT REG32(SDIO + 0x48U) /*!< SDIO FIFO counter register */ -#define SDIO_FIFO REG32(SDIO + 0x80U) /*!< SDIO FIFO data register */ +#define SDIO_PWRCTL REG32(SDIO + 0x00000000U) /*!< SDIO power control register */ +#define SDIO_CLKCTL REG32(SDIO + 0x00000004U) /*!< SDIO clock control register */ +#define SDIO_CMDAGMT REG32(SDIO + 0x00000008U) /*!< SDIO command argument register */ +#define SDIO_CMDCTL REG32(SDIO + 0x0000000CU) /*!< SDIO command control register */ +#define SDIO_RSPCMDIDX REG32(SDIO + 0x00000010U) /*!< SDIO command index response register */ +#define SDIO_RESP0 REG32(SDIO + 0x00000014U) /*!< SDIO response register 0 */ +#define SDIO_RESP1 REG32(SDIO + 0x00000018U) /*!< SDIO response register 1 */ +#define SDIO_RESP2 REG32(SDIO + 0x0000001CU) /*!< SDIO response register 2 */ +#define SDIO_RESP3 REG32(SDIO + 0x00000020U) /*!< SDIO response register 3 */ +#define SDIO_DATATO REG32(SDIO + 0x00000024U) /*!< SDIO data timeout register */ +#define SDIO_DATALEN REG32(SDIO + 0x00000028U) /*!< SDIO data length register */ +#define SDIO_DATACTL REG32(SDIO + 0x0000002CU) /*!< SDIO data control register */ +#define SDIO_DATACNT REG32(SDIO + 0x00000030U) /*!< SDIO data counter register */ +#define SDIO_STAT REG32(SDIO + 0x00000034U) /*!< SDIO status register */ +#define SDIO_INTC REG32(SDIO + 0x00000038U) /*!< SDIO interrupt clear register */ +#define SDIO_INTEN REG32(SDIO + 0x0000003CU) /*!< SDIO interrupt enable register */ +#define SDIO_FIFOCNT REG32(SDIO + 0x00000048U) /*!< SDIO FIFO counter register */ +#define SDIO_FIFO REG32(SDIO + 0x00000080U) /*!< SDIO FIFO data register */ /* bits definitions */ /* SDIO_PWRCTL */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h index 5eb3803..1c2ccdf 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h @@ -2,35 +2,33 @@ \file gd32f4xx_spi.h \brief definitions for the SPI - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -53,27 +51,27 @@ OF SUCH DAMAGE. #define I2S2_ADD (I2S_ADD_BASE + 0x00000C00U) /* SPI registers definitions */ -#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ -#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ -#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ -#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ -#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ -#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ -#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ -#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ -#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ -#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad mode control register */ +#define SPI_CTL0(spix) REG32((spix) + 0x00000000U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x00000004U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x00000008U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0000000CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x00000010U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x00000014U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x00000018U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x0000001CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x00000020U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x00000080U) /*!< SPI quad mode control register */ /* I2S_ADD registers definitions */ -#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00U) /*!< I2S_ADD control register 0 */ -#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x04U) /*!< I2S_ADD control register 1*/ -#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x08U) /*!< I2S_ADD status register */ -#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0CU) /*!< I2S_ADD data register */ -#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x10U) /*!< I2S_ADD CRC polynomial register */ -#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x14U) /*!< I2S_ADD receive CRC register */ -#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x18U) /*!< I2S_ADD transmit CRC register */ -#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x1CU) /*!< I2S_ADD I2S control register */ -#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x20U) /*!< I2S_ADD I2S clock prescaler register */ +#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00000000U) /*!< I2S_ADD control register 0 */ +#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x00000004U) /*!< I2S_ADD control register 1*/ +#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x00000008U) /*!< I2S_ADD status register */ +#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0000000CU) /*!< I2S_ADD data register */ +#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x00000010U) /*!< I2S_ADD CRC polynomial register */ +#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x00000014U) /*!< I2S_ADD receive CRC register */ +#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x00000018U) /*!< I2S_ADD transmit CRC register */ +#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x0000001CU) /*!< I2S_ADD I2S control register */ +#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x00000020U) /*!< I2S_ADD I2S clock prescaler register */ /* bits definitions */ /* SPI_CTL0 */ @@ -146,8 +144,7 @@ OF SUCH DAMAGE. /* constants definitions */ /* SPI and I2S parameter struct definitions */ -typedef struct -{ +typedef struct { uint32_t device_mode; /*!< SPI master or slave */ uint32_t trans_mode; /*!< SPI transtype */ uint32_t frame_size; /*!< SPI frame size */ @@ -155,7 +152,7 @@ typedef struct uint32_t endian; /*!< SPI big endian or little endian */ uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ uint32_t prescale; /*!< SPI prescale factor */ -}spi_parameter_struct; +} spi_parameter_struct; /* SPI mode definitions */ #define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ @@ -241,7 +238,7 @@ typedef struct #define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ #define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ -/* SPI DMA constants definitions */ +/* SPI DMA constants definitions */ #define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ #define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ @@ -263,7 +260,7 @@ typedef struct #define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ #define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ -/* SPI/I2S flag definitions */ +/* SPI/I2S flag definitions */ #define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ #define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ #define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ @@ -283,19 +280,19 @@ typedef struct /* initialization functions */ /* deinitialize SPI and I2S */ void spi_i2s_deinit(uint32_t spi_periph); -/* initialize the parameters of SPI struct with the default values */ -void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize the parameters of SPI struct with default values */ +void spi_struct_para_init(spi_parameter_struct *spi_struct); /* initialize SPI parameter */ -void spi_init(uint32_t spi_periph,spi_parameter_struct* spi_struct); +void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct); /* enable SPI */ void spi_enable(uint32_t spi_periph); /* disable SPI */ void spi_disable(uint32_t spi_periph); /* initialize I2S parameter */ -void i2s_init(uint32_t spi_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl); +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl); /* configure I2S prescale */ -void i2s_psc_config(uint32_t spi_periph,uint32_t i2s_audiosample,uint32_t i2s_frameformat,uint32_t i2s_mckout); +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout); /* enable I2S */ void i2s_enable(uint32_t spi_periph); /* disable I2S */ @@ -312,24 +309,28 @@ void spi_nss_internal_high(uint32_t spi_periph); void spi_nss_internal_low(uint32_t spi_periph); /* SPI DMA functions */ -/* enable SPI DMA */ -void spi_dma_enable(uint32_t spi_periph,uint8_t spi_dma); -/* disable SPI DMA */ -void spi_dma_disable(uint32_t spi_periph,uint8_t spi_dma); +/* enable SPI DMA send or receive */ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma); +/* diable SPI DMA send or receive */ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma); /* SPI/I2S transfer configure functions */ /* configure SPI/I2S data frame format */ -void spi_i2s_data_frame_format_config(uint32_t spi_periph,uint16_t frame_format); +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); /* SPI transmit data */ -void spi_i2s_data_transmit(uint32_t spi_periph,uint16_t data); +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); /* SPI receive data */ uint16_t spi_i2s_data_receive(uint32_t spi_periph); /* configure SPI bidirectional transfer direction */ -void spi_bidirectional_transfer_config(uint32_t spi_periph,uint32_t transfer_direction); +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); +/* configure i2s full duplex mode */ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl, uint32_t i2s_frameformat); +/* clear TI Mode Format Error flag status */ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag); /* SPI CRC functions */ /* set SPI CRC polynomial */ -void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly); +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly); /* get SPI CRC polynomial */ uint16_t spi_crc_polynomial_get(uint32_t spi_periph); /* turn on SPI CRC function */ @@ -339,7 +340,9 @@ void spi_crc_off(uint32_t spi_periph); /* SPI next data is CRC value */ void spi_crc_next(uint32_t spi_periph); /* get SPI CRC send value or receive value */ -uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc); +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t spi_crc); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); /* SPI TI mode functions */ /* enable SPI TI mode */ @@ -347,33 +350,28 @@ void spi_ti_mode_enable(uint32_t spi_periph); /* disable SPI TI mode */ void spi_ti_mode_disable(uint32_t spi_periph); -/* configure i2s full duplex mode */ -void i2s_full_duplex_mode_config(uint32_t i2s_add_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl,uint32_t i2s_frameformat); - /* quad wire SPI functions */ /* enable quad wire SPI */ -void qspi_enable(uint32_t spi_periph); +void spi_quad_enable(uint32_t spi_periph); /* disable quad wire SPI */ -void qspi_disable(uint32_t spi_periph); +void spi_quad_disable(uint32_t spi_periph); /* enable quad wire SPI write */ -void qspi_write_enable(uint32_t spi_periph); +void spi_quad_write_enable(uint32_t spi_periph); /* enable quad wire SPI read */ -void qspi_read_enable(uint32_t spi_periph); -/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ -void qspi_io23_output_enable(uint32_t spi_periph); -/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ -void qspi_io23_output_disable(uint32_t spi_periph); - -/* flag & interrupt functions */ -/* enable SPI interrupt */ -void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t spi_i2s_int); -/* disable SPI interrupt */ -void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t spi_i2s_int); -/* get SPI and I2S interrupt status*/ -FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph,uint8_t spi_i2s_int); +void spi_quad_read_enable(uint32_t spi_periph); +/* enable SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_enable(uint32_t spi_periph); +/* disable SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_disable(uint32_t spi_periph); + +/* flag and interrupt functions */ /* get SPI and I2S flag status */ -FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t spi_i2s_flag); -/* clear SPI CRC error flag status */ -void spi_crc_error_clear(uint32_t spi_periph); +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* enable SPI and I2S interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt); +/* disable SPI and I2S interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S interrupt status*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); #endif /* GD32F4XX_SPI_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h index 749517f..ae32ff8 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h @@ -2,13 +2,11 @@ \file gd32f4xx_syscfg.h \brief definitions for the SYSCFG - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h index bc38efa..6e5fc52 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h @@ -2,14 +2,11 @@ \file gd32f4xx_timer.h \brief definitions for the TIMER - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. - All rights reserved. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -341,8 +338,6 @@ typedef struct #define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ #define TIMER_INT_FLAG_BRK TIMER_INTF_BRKIF - - /* TIMER DMA source enable */ #define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */ #define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */ @@ -418,8 +413,8 @@ typedef struct #define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ /* TIMER prescaler reload mode */ -#define TIMER_PSC_RELOAD_NOW ((uint32_t)0x00000000U) /*!< the prescaler is loaded right now */ -#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000001U) /*!< the prescaler is loaded at the next update event */ +#define TIMER_PSC_RELOAD_NOW ((uint32_t)0x00000000U) /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000001U) /*!< the prescaler is loaded at the next update event */ /* count direction */ #define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ @@ -432,12 +427,12 @@ typedef struct #define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS= fTIMER_CK/4 */ /* single pulse mode */ -#define TIMER_SP_MODE_SINGLE ((uint32_t)0x00000000U) /*!< single pulse mode */ -#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000001U) /*!< repetitive pulse mode */ +#define TIMER_SP_MODE_SINGLE ((uint32_t)0x00000000U) /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000001U) /*!< repetitive pulse mode */ /* update source */ -#define TIMER_UPDATE_SRC_REGULAR ((uint32_t)0x00000000U) /*!< update generate only by counter overflow/underflow */ -#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000001U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ +#define TIMER_UPDATE_SRC_REGULAR ((uint32_t)0x00000000U) /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000001U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ /* run mode off-state configure */ #define TIMER_ROS_STATE_ENABLE ((uint16_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ @@ -539,7 +534,7 @@ typedef struct #define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ /* trigger selection */ -#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) #define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ #define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ #define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ @@ -563,17 +558,17 @@ typedef struct /* slave mode control */ #define SMCFG_SMC(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0U)) #define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ -#define TIMER_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ -#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ -#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder mode 2 */ +#define TIMER_QUAD_DECODER_MODE0 SMCFG_SMC(1) /*!< quadrature decoder mode 0 */ +#define TIMER_QUAD_DECODER_MODE1 SMCFG_SMC(2) /*!< quadrature decoder mode 1 */ +#define TIMER_QUAD_DECODER_MODE2 SMCFG_SMC(3) /*!< quadrature decoder mode 2 */ #define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ #define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ #define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ #define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ /* master slave mode selection */ -#define TIMER_MASTER_SLAVE_MODE_ENABLE ((uint32_t)0x00000000U) /*!< master slave mode enable */ -#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000001U) /*!< master slave mode disable */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE ((uint32_t)0x00000000U) /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000001U) /*!< master slave mode disable */ /* external trigger prescaler */ #define SMCFG_ETPSC(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12U)) @@ -587,8 +582,8 @@ typedef struct #define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ /* channel 0 trigger input selection */ -#define TIMER_HALLINTERFACE_ENABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode enable */ -#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000001U) /*!< TIMER hall sensor mode disable */ +#define TIMER_HALLINTERFACE_ENABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000001U) /*!< TIMER hall sensor mode disable */ /* timer1 internal trigger input1 remap */ #define TIMER1_IRMP(regval) (BITS(10, 11) & ((uint32_t)(regval) << 10U)) @@ -610,8 +605,8 @@ typedef struct #define TIMER10_ITI1_RMP_RTC_HXTAL_DIV TIMER10_IRMP(2) /*!< timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) */ /* timerx(x=0,1,2,13,14,15,16) write cc register selection */ -#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */ -#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ /* the output value selection */ #define TIMER_OUTSEL_ENABLE ((uint16_t)0x0001U) /*!< output value selection enable */ @@ -660,20 +655,6 @@ void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); /* configure TIMER update source */ void timer_update_source_config(uint32_t timer_periph, uint32_t update); -/* TIMER interrupt and flag*/ -/* enable the TIMER interrupt */ -void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); -/* disable the TIMER interrupt */ -void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); -/* get timer interrupt flag */ -FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); -/* clear TIMER interrupt flag */ -void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); -/* get TIMER flags */ -FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); -/* clear TIMER flags */ -void timer_flag_clear(uint32_t timer_periph, uint32_t flag); - /* timer DMA and event*/ /* enable the TIMER DMA */ void timer_dma_enable(uint32_t timer_periph, uint16_t dma); @@ -778,4 +759,18 @@ void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel); /* configure TIMER output value selection */ void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel); +/* TIMER interrupt and flag*/ +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get timer interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); + #endif /* GD32F4XX_TIMER_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h index c3078b7..1413790 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h @@ -1,36 +1,34 @@ /*! \file gd32f4xx_tli.h \brief definitions for the TLI - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -40,37 +38,37 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* TLI definitions */ -#define TLI TLI_BASE /*!< TLI base address */ +#define TLI TLI_BASE /*!< TLI base address */ /* TLI layer definitions */ -#define LAYER0 TLI_BASE /*!< TLI layer0 base address */ -#define LAYER1 (TLI_BASE+0x80) /*!< TLI layer1 base address */ +#define LAYER0 TLI_BASE /*!< TLI layer0 base address */ +#define LAYER1 (TLI_BASE + 0x00000080U) /*!< TLI layer1 base address */ /* registers definitions */ -#define TLI_SPSZ REG32(TLI + 0x08U) /*!< TLI synchronous pulse size register */ -#define TLI_BPSZ REG32(TLI + 0x0CU) /*!< TLI back-porch size register */ -#define TLI_ASZ REG32(TLI + 0x10U) /*!< TLI active size register */ -#define TLI_TSZ REG32(TLI + 0x14U) /*!< TLI total size register */ -#define TLI_CTL REG32(TLI + 0x18U) /*!< TLI control register */ -#define TLI_RL REG32(TLI + 0x24U) /*!< TLI reload Layer register */ -#define TLI_BGC REG32(TLI + 0x2CU) /*!< TLI background color register */ -#define TLI_INTEN REG32(TLI + 0x34U) /*!< TLI interrupt enable register */ -#define TLI_INTF REG32(TLI + 0x38U) /*!< TLI interrupt flag register */ -#define TLI_INTC REG32(TLI + 0x3CU) /*!< TLI interrupt flag clear register */ -#define TLI_LM REG32(TLI + 0x40U) /*!< TLI line mark register */ -#define TLI_CPPOS REG32(TLI + 0x44U) /*!< TLI current pixel position register */ -#define TLI_STAT REG32(TLI + 0x48U) /*!< TLI status register */ -#define TLI_LxCTL(layerx) REG32((layerx) + 0x84U) /*!< TLI layer x control register */ -#define TLI_LxHPOS(layerx) REG32((layerx) + 0x88U) /*!< TLI layer x horizontal position parameters register */ -#define TLI_LxVPOS(layerx) REG32((layerx) + 0x8CU) /*!< TLI layer x vertical position parameters register */ -#define TLI_LxCKEY(layerx) REG32((layerx) + 0x90U) /*!< TLI layer x color key register */ -#define TLI_LxPPF(layerx) REG32((layerx) + 0x94U) /*!< TLI layer x packeted pixel format register */ -#define TLI_LxSA(layerx) REG32((layerx) + 0x98U) /*!< TLI layer x specified alpha register */ -#define TLI_LxDC(layerx) REG32((layerx) + 0x9CU) /*!< TLI layer x default color register */ -#define TLI_LxBLEND(layerx) REG32((layerx) + 0xA0U) /*!< TLI layer x blending register */ -#define TLI_LxFBADDR(layerx) REG32((layerx) + 0xACU) /*!< TLI layer x frame base address register */ -#define TLI_LxFLLEN(layerx) REG32((layerx) + 0xB0U) /*!< TLI layer x frame line length register */ -#define TLI_LxFTLN(layerx) REG32((layerx) + 0xB4U) /*!< TLI layer x frame total line number register */ -#define TLI_LxLUT(layerx) REG32((layerx) + 0xC4U) /*!< TLI layer x look up table register */ +#define TLI_SPSZ REG32(TLI + 0x00000008U) /*!< TLI synchronous pulse size register */ +#define TLI_BPSZ REG32(TLI + 0x0000000CU) /*!< TLI back-porch size register */ +#define TLI_ASZ REG32(TLI + 0x00000010U) /*!< TLI active size register */ +#define TLI_TSZ REG32(TLI + 0x00000014U) /*!< TLI total size register */ +#define TLI_CTL REG32(TLI + 0x00000018U) /*!< TLI control register */ +#define TLI_RL REG32(TLI + 0x00000024U) /*!< TLI reload Layer register */ +#define TLI_BGC REG32(TLI + 0x0000002CU) /*!< TLI background color register */ +#define TLI_INTEN REG32(TLI + 0x00000034U) /*!< TLI interrupt enable register */ +#define TLI_INTF REG32(TLI + 0x00000038U) /*!< TLI interrupt flag register */ +#define TLI_INTC REG32(TLI + 0x0000003CU) /*!< TLI interrupt flag clear register */ +#define TLI_LM REG32(TLI + 0x00000040U) /*!< TLI line mark register */ +#define TLI_CPPOS REG32(TLI + 0x00000044U) /*!< TLI current pixel position register */ +#define TLI_STAT REG32(TLI + 0x00000048U) /*!< TLI status register */ +#define TLI_LxCTL(layerx) REG32((layerx) + 0x00000084U) /*!< TLI layer x control register */ +#define TLI_LxHPOS(layerx) REG32((layerx) + 0x00000088U) /*!< TLI layer x horizontal position parameters register */ +#define TLI_LxVPOS(layerx) REG32((layerx) + 0x0000008CU) /*!< TLI layer x vertical position parameters register */ +#define TLI_LxCKEY(layerx) REG32((layerx) + 0x00000090U) /*!< TLI layer x color key register */ +#define TLI_LxPPF(layerx) REG32((layerx) + 0x00000094U) /*!< TLI layer x packeted pixel format register */ +#define TLI_LxSA(layerx) REG32((layerx) + 0x00000098U) /*!< TLI layer x specified alpha register */ +#define TLI_LxDC(layerx) REG32((layerx) + 0x0000009CU) /*!< TLI layer x default color register */ +#define TLI_LxBLEND(layerx) REG32((layerx) + 0x000000A0U) /*!< TLI layer x blending register */ +#define TLI_LxFBADDR(layerx) REG32((layerx) + 0x000000ACU) /*!< TLI layer x frame base address register */ +#define TLI_LxFLLEN(layerx) REG32((layerx) + 0x000000B0U) /*!< TLI layer x frame line length register */ +#define TLI_LxFTLN(layerx) REG32((layerx) + 0x000000B4U) /*!< TLI layer x frame total line number register */ +#define TLI_LxLUT(layerx) REG32((layerx) + 0x000000C4U) /*!< TLI layer x look up table register */ /* bits definitions */ /* TLI_SPSZ */ @@ -85,7 +83,7 @@ OF SUCH DAMAGE. #define TLI_ASZ_VASZ BITS(0,11) /*!< size of the vertical active area width plus back porch and synchronous pulse */ #define TLI_ASZ_HASZ BITS(16,27) /*!< size of the horizontal active area width plus back porch and synchronous pulse */ -/* TLI_SPSZ */ +/* TLI_TSZ */ #define TLI_TSZ_VTSZ BITS(0,11) /*!< vertical total size of the display, including active area, back porch, synchronous pulse and front porch */ #define TLI_TSZ_HTSZ BITS(16,27) /*!< horizontal total size of the display, including active area, back porch, synchronous pulse and front porch */ @@ -138,7 +136,7 @@ OF SUCH DAMAGE. #define TLI_STAT_VDE BIT(0) /*!< current VDE status */ #define TLI_STAT_HDE BIT(1) /*!< current HDE status */ #define TLI_STAT_VS BIT(2) /*!< current VS status of the TLI */ -#define TLI_STAT_HS BIT(3) /*!< current HS status of the TLI */ +#define TLI_STAT_HS BIT(3) /*!< current HS status of the TLI */ /* TLI_LxCTL */ #define TLI_LxCTL_LEN BIT(0) /*!< layer enable */ @@ -192,8 +190,7 @@ OF SUCH DAMAGE. /* constants definitions */ /* TLI parameter struct definitions */ -typedef struct -{ +typedef struct { uint16_t synpsz_vpsz; /*!< size of the vertical synchronous pulse */ uint16_t synpsz_hpsz; /*!< size of the horizontal synchronous pulse */ uint16_t backpsz_vbpsz; /*!< size of the vertical back porch plus synchronous pulse */ @@ -209,11 +206,10 @@ typedef struct uint32_t signalpolarity_vs; /*!< vertical pulse polarity selection */ uint32_t signalpolarity_de; /*!< data enable polarity selection */ uint32_t signalpolarity_pixelck; /*!< pixel clock polarity selection */ -}tli_parameter_struct; +} tli_parameter_struct; /* TLI layer parameter struct definitions */ -typedef struct -{ +typedef struct { uint16_t layer_window_rightpos; /*!< window right position */ uint16_t layer_window_leftpos; /*!< window left position */ uint16_t layer_window_bottompos; /*!< window bottom position */ @@ -230,29 +226,27 @@ typedef struct uint16_t layer_frame_buf_stride_offset; /*!< frame buffer stride offset */ uint16_t layer_frame_line_length; /*!< frame line length */ uint16_t layer_frame_total_line_number; /*!< frame total line number */ -}tli_layer_parameter_struct; +} tli_layer_parameter_struct; /* TLI layer LUT parameter struct definitions */ -typedef struct -{ +typedef struct { uint32_t layer_table_addr; /*!< look up table write address */ uint8_t layer_lut_channel_red; /*!< red channel of a LUT entry */ uint8_t layer_lut_channel_green; /*!< green channel of a LUT entry */ uint8_t layer_lut_channel_blue; /*!< blue channel of a LUT entry */ -}tli_layer_lut_parameter_struct; +} tli_layer_lut_parameter_struct; /* packeted pixel format */ -typedef enum -{ - LAYER_PPF_ARGB8888, /*!< layerx pixel format ARGB8888 */ - LAYER_PPF_RGB888, /*!< layerx pixel format RGB888 */ - LAYER_PPF_RGB565, /*!< layerx pixel format RGB565 */ - LAYER_PPF_ARGB1555, /*!< layerx pixel format ARGB1555 */ - LAYER_PPF_ARGB4444, /*!< layerx pixel format ARGB4444 */ - LAYER_PPF_L8, /*!< layerx pixel format L8 */ - LAYER_PPF_AL44, /*!< layerx pixel format AL44 */ - LAYER_PPF_AL88 /*!< layerx pixel format AL88 */ -}tli_layer_ppf_enum; +typedef enum { + LAYER_PPF_ARGB8888 = 0U, /*!< layerx pixel format ARGB8888 */ + LAYER_PPF_RGB888, /*!< layerx pixel format RGB888 */ + LAYER_PPF_RGB565, /*!< layerx pixel format RGB565 */ + LAYER_PPF_ARGB1555, /*!< layerx pixel format ARGB1555 */ + LAYER_PPF_ARGB4444, /*!< layerx pixel format ARGB4444 */ + LAYER_PPF_L8, /*!< layerx pixel format L8 */ + LAYER_PPF_AL44, /*!< layerx pixel format AL44 */ + LAYER_PPF_AL88 /*!< layerx pixel format AL88 */ +} tli_layer_ppf_enum; /* TLI flags */ #define TLI_FLAG_VDE TLI_STAT_VDE /*!< current VDE status */ @@ -287,10 +281,12 @@ typedef enum /* horizontal pulse polarity selection */ #define TLI_HSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< horizontal synchronous pulse active low */ #define TLI_HSYN_ACTLIVE_HIGHT TLI_CTL_HPPS /*!< horizontal synchronous pulse active high */ +#define TLI_HSYN_ACTLIVE_HIGH TLI_HSYN_ACTLIVE_HIGHT /*!< horizontal synchronous pulse active high */ /* vertical pulse polarity selection */ #define TLI_VSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< vertical synchronous pulse active low */ #define TLI_VSYN_ACTLIVE_HIGHT TLI_CTL_VPPS /*!< vertical synchronous pulse active high */ +#define TLI_VSYN_ACTLIVE_HIGH TLI_VSYN_ACTLIVE_HIGHT /*!< vertical synchronous pulse active high */ /* pixel clock polarity selection */ #define TLI_PIXEL_CLOCK_TLI ((uint32_t)0x00000000U) /*!< pixel clock is TLI clock */ @@ -299,6 +295,7 @@ typedef enum /* data enable polarity selection */ #define TLI_DE_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< data enable active low */ #define TLI_DE_ACTLIVE_HIGHT TLI_CTL_DEPS /*!< data enable active high */ +#define TLI_DE_ACTLIVE_HIGH TLI_DE_ACTLIVE_HIGHT /*!< data enable active high */ /* alpha calculation factor 1 of blending method */ #define LxBLEND_ACF1(regval) (BITS(8,10) & ((uint32_t)(regval)<<8)) @@ -314,7 +311,7 @@ typedef enum /* initialization functions, TLI enable or disable, TLI reload mode configuration */ /* deinitialize TLI registers */ void tli_deinit(void); -/* initialize the parameters of TLI parameter structure with the default values, it is suggested +/* initialize the parameters of TLI parameter structure with the default values, it is suggested that call this function after a tli_parameter_struct structure is defined */ void tli_struct_para_init(tli_parameter_struct *tli_struct); /* initialize TLI */ @@ -329,20 +326,20 @@ void tli_disable(void); void tli_reload_config(uint8_t reload_mod); /* TLI layer configuration functions */ -/* initialize the parameters of TLI layer structure with the default values, it is suggested +/* initialize the parameters of TLI layer structure with the default values, it is suggested that call this function after a tli_layer_parameter_struct structure is defined */ void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct); /* initialize TLI layer */ -void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct); +void tli_layer_init(uint32_t layerx, tli_layer_parameter_struct *layer_struct); /* reconfigure window position */ -void tli_layer_window_offset_modify(uint32_t layerx,uint16_t offset_x,uint16_t offset_y); -/* initialize the parameters of TLI layer LUT structure with the default values, it is suggested +void tli_layer_window_offset_modify(uint32_t layerx, uint16_t offset_x, uint16_t offset_y); +/* initialize the parameters of TLI layer LUT structure with the default values, it is suggested that call this function after a tli_layer_lut_parameter_struct structure is defined */ void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct); /* initialize TLI layer LUT */ -void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct); +void tli_lut_init(uint32_t layerx, tli_layer_lut_parameter_struct *lut_struct); /* initialize TLI layer color key */ -void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey); +void tli_color_key_init(uint32_t layerx, uint8_t redkey, uint8_t greenkey, uint8_t bluekey); /* enable TLI layer */ void tli_layer_enable(uint32_t layerx); /* disable TLI layer */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h index 5bdcb2f..ff78ab5 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h @@ -2,13 +2,11 @@ \file gd32f4xx_trng.h \brief definitions for the TRNG - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -43,14 +41,14 @@ OF SUCH DAMAGE. #define TRNG TRNG_BASE /* registers definitions */ -#define TRNG_CTL REG32(TRNG + 0x00U) /*!< control register */ -#define TRNG_STAT REG32(TRNG + 0x04U) /*!< status register */ -#define TRNG_DATA REG32(TRNG + 0x08U) /*!< data register */ +#define TRNG_CTL REG32(TRNG + 0x00000000U) /*!< control register */ +#define TRNG_STAT REG32(TRNG + 0x00000004U) /*!< status register */ +#define TRNG_DATA REG32(TRNG + 0x00000008U) /*!< data register */ /* bits definitions */ /* TRNG_CTL */ #define TRNG_CTL_TRNGEN BIT(2) /*!< TRNG enable bit */ -#define TRNG_CTL_IE BIT(3) /*!< interrupt enable bit */ +#define TRNG_CTL_TRNGIE BIT(3) /*!< interrupt enable bit */ /* TRNG_STAT */ #define TRNG_STAT_DRDY BIT(0) /*!< random data ready status bit */ @@ -60,45 +58,43 @@ OF SUCH DAMAGE. #define TRNG_STAT_SEIF BIT(6) /*!< seed error interrupt flag */ /* TRNG_DATA */ -#define TRNG_DATA_TRNDATA BITS(0,31) /*!< 32-Bit Random data */ +#define TRNG_DATA_TRNGDATA BITS(0,31) /*!< 32-Bit Random data */ /* constants definitions */ -/* trng status flag */ -typedef enum -{ +/* TRNG status flag */ +typedef enum { TRNG_FLAG_DRDY = TRNG_STAT_DRDY, /*!< random Data ready status */ TRNG_FLAG_CECS = TRNG_STAT_CECS, /*!< clock error current status */ TRNG_FLAG_SECS = TRNG_STAT_SECS /*!< seed error current status */ -}trng_flag_enum; +} trng_flag_enum; -/* trng inerrupt flag */ -typedef enum -{ +/* TRNG inerrupt flag */ +typedef enum { TRNG_INT_FLAG_CEIF = TRNG_STAT_CEIF, /*!< clock error interrupt flag */ TRNG_INT_FLAG_SEIF = TRNG_STAT_SEIF /*!< seed error interrupt flag */ -}trng_int_flag_enum; +} trng_int_flag_enum; /* function declarations */ /* initialization functions */ -/* deinitialize the TRNG */ +/* reset TRNG */ void trng_deinit(void); -/* enable the TRNG interface */ +/* enable TRNG */ void trng_enable(void); -/* disable the TRNG interface */ +/* disable TRNG */ void trng_disable(void); /* get the true random data */ uint32_t trng_get_true_random_data(void); -/* flag & interrupt functions */ -/* trng interrupt enable */ +/* interrupt & flag functions */ +/* enable TRNG interrupt */ void trng_interrupt_enable(void); -/* trng interrupt disable */ +/* disable TRNG interrupt */ void trng_interrupt_disable(void); -/* get the trng status flags */ +/* get TRNG flag status */ FlagStatus trng_flag_get(trng_flag_enum flag); -/* get the trng interrupt flags */ +/* get TRNG interrupt flag status */ FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag); -/* clear the trng interrupt flags */ +/* clear TRNG interrupt flag status */ void trng_interrupt_flag_clear(trng_int_flag_enum int_flag); #endif /* GD32F4XX_TRNG_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h index d8bf598..fb3152b 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h @@ -1,36 +1,34 @@ /*! \file gd32f4xx_usart.h \brief definitions for the USART - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -64,94 +62,94 @@ OF SUCH DAMAGE. /* bits definitions */ /* USARTx_STAT0 */ -#define USART_STAT0_PERR BIT(0) /*!< parity error flag */ -#define USART_STAT0_FERR BIT(1) /*!< frame error flag */ -#define USART_STAT0_NERR BIT(2) /*!< noise error flag */ -#define USART_STAT0_ORERR BIT(3) /*!< overrun error */ -#define USART_STAT0_IDLEF BIT(4) /*!< IDLE frame detected flag */ -#define USART_STAT0_RBNE BIT(5) /*!< read data buffer not empty */ -#define USART_STAT0_TC BIT(6) /*!< transmission complete */ -#define USART_STAT0_TBE BIT(7) /*!< transmit data buffer empty */ -#define USART_STAT0_LBDF BIT(8) /*!< LIN break detected flag */ -#define USART_STAT0_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT0_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT0_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT0_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT0_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT0_IDLEF BIT(4) /*!< IDLE frame detected flag */ +#define USART_STAT0_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT0_TC BIT(6) /*!< transmission complete */ +#define USART_STAT0_TBE BIT(7) /*!< transmit data buffer empty */ +#define USART_STAT0_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT0_CTSF BIT(9) /*!< CTS change flag */ /* USARTx_DATA */ -#define USART_DATA_DATA BITS(0,8) /*!< transmit or read data value */ +#define USART_DATA_DATA BITS(0,8) /*!< transmit or read data value */ /* USARTx_BAUD */ -#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction part of baud-rate divider */ -#define USART_BAUD_INTDIV BITS(4,15) /*!< integer part of baud-rate divider */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction part of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer part of baud-rate divider */ /* USARTx_CTL0 */ -#define USART_CTL0_SBKCMD BIT(0) /*!< send break command */ -#define USART_CTL0_RWU BIT(1) /*!< receiver wakeup from mute mode */ -#define USART_CTL0_REN BIT(2) /*!< receiver enable */ -#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ -#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ -#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ -#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ -#define USART_CTL0_TBEIE BIT(7) /*!< transmitter buffer empty interrupt enable */ -#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ -#define USART_CTL0_PM BIT(9) /*!< parity mode */ -#define USART_CTL0_PCEN BIT(10) /*!< parity check function enable */ -#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ -#define USART_CTL0_WL BIT(12) /*!< word length */ -#define USART_CTL0_UEN BIT(13) /*!< USART enable */ -#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_SBKCMD BIT(0) /*!< send break command */ +#define USART_CTL0_RWU BIT(1) /*!< receiver wakeup from mute mode */ +#define USART_CTL0_REN BIT(2) /*!< enable receiver */ +#define USART_CTL0_TEN BIT(3) /*!< enable transmitter */ +#define USART_CTL0_IDLEIE BIT(4) /*!< enable idle line detected interrupt */ +#define USART_CTL0_RBNEIE BIT(5) /*!< enable read data buffer not empty interrupt and overrun error interrupt */ +#define USART_CTL0_TCIE BIT(6) /*!< enable transmission complete interrupt */ +#define USART_CTL0_TBEIE BIT(7) /*!< enable transmitter buffer empty interrupt */ +#define USART_CTL0_PERRIE BIT(8) /*!< enable parity error interrupt */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< enable parity check function */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_UEN BIT(13) /*!< enable USART */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ /* USARTx_CTL1 */ -#define USART_CTL1_ADDR BITS(0,3) /*!< address of USART */ -#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ -#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detected interrupt eanble */ -#define USART_CTL1_CLEN BIT(8) /*!< CK length */ -#define USART_CTL1_CPH BIT(9) /*!< CK phase */ -#define USART_CTL1_CPL BIT(10) /*!< CK polarity */ -#define USART_CTL1_CKEN BIT(11) /*!< CK pin enable */ -#define USART_CTL1_STB BITS(12,13) /*!< STOP bits length */ -#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_ADDR BITS(0,3) /*!< address of USART */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< enable LIN break detected interrupt */ +#define USART_CTL1_CLEN BIT(8) /*!< CK length */ +#define USART_CTL1_CPH BIT(9) /*!< CK phase */ +#define USART_CTL1_CPL BIT(10) /*!< CK polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< enable CK pin */ +#define USART_CTL1_STB BITS(12,13) /*!< STOP bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< enable LIN mode */ /* USARTx_CTL2 */ -#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable */ -#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ -#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ -#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ -#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ -#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ -#define USART_CTL2_DENR BIT(6) /*!< DMA request enable for reception */ -#define USART_CTL2_DENT BIT(7) /*!< DMA request enable for transmission */ -#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ -#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ -#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ -#define USART_CTL2_OSB BIT(11) /*!< one sample bit method */ +#define USART_CTL2_ERRIE BIT(0) /*!< enable error interrupt */ +#define USART_CTL2_IREN BIT(1) /*!< enable IrDA mode */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< enable half-duplex */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< enable smartcard mode */ +#define USART_CTL2_DENR BIT(6) /*!< enable DMA request for reception */ +#define USART_CTL2_DENT BIT(7) /*!< enable DMA request for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< enable RTS */ +#define USART_CTL2_CTSEN BIT(9) /*!< enable CTS */ +#define USART_CTL2_CTSIE BIT(10) /*!< enable CTS interrupt */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit method */ /* USARTx_GP */ -#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ -#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ - +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + /* USARTx_CTL3 */ -#define USART_CTL3_RTEN BIT(0) /*!< receiver timeout enable */ -#define USART_CTL3_SCRTNUM BITS(1,3) /*!< smartcard auto-retry number */ -#define USART_CTL3_RTIE BIT(4) /*!< interrupt enable bit of receive timeout event */ -#define USART_CTL3_EBIE BIT(5) /*!< interrupt enable bit of end of block event */ -#define USART_CTL3_RINV BIT(8) /*!< RX pin level inversion */ -#define USART_CTL3_TINV BIT(9) /*!< TX pin level inversion */ -#define USART_CTL3_DINV BIT(10) /*!< data bit level inversion */ -#define USART_CTL3_MSBF BIT(11) /*!< most significant bit first */ +#define USART_CTL3_RTEN BIT(0) /*!< enable receiver timeout */ +#define USART_CTL3_SCRTNUM BITS(1,3) /*!< smartcard auto-retry number */ +#define USART_CTL3_RTIE BIT(4) /*!< interrupt enable bit of receive timeout event */ +#define USART_CTL3_EBIE BIT(5) /*!< interrupt enable bit of end of block event */ +#define USART_CTL3_RINV BIT(8) /*!< RX pin level inversion */ +#define USART_CTL3_TINV BIT(9) /*!< TX pin level inversion */ +#define USART_CTL3_DINV BIT(10) /*!< data bit level inversion */ +#define USART_CTL3_MSBF BIT(11) /*!< most significant bit first */ /* USARTx_RT */ -#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ -#define USART_RT_BL BITS(24,31) /*!< block length */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ /* USARTx_STAT1 */ -#define USART_STAT1_RTF BIT(11) /*!< receiver timeout flag */ -#define USART_STAT1_EBF BIT(12) /*!< end of block flag */ -#define USART_STAT1_BSY BIT(16) /*!< busy flag */ +#define USART_STAT1_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT1_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT1_BSY BIT(16) /*!< busy flag */ /* USARTx_CHC */ -#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ -#define USART_CHC_PCM BIT(1) /*!< parity check coherence mode */ -#define USART_CHC_BCM BIT(2) /*!< break frame coherence mode */ -#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_PCM BIT(1) /*!< parity check coherence mode */ +#define USART_CHC_BCM BIT(2) /*!< break frame coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ /* constants definitions */ /* define the USART bit position and its register index offset */ @@ -164,17 +162,16 @@ OF SUCH DAMAGE. #define USART_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) /* register offset */ -#define USART_STAT0_REG_OFFSET 0x00U /*!< STAT0 register offset */ -#define USART_STAT1_REG_OFFSET 0x88U /*!< STAT1 register offset */ -#define USART_CTL0_REG_OFFSET 0x0CU /*!< CTL0 register offset */ -#define USART_CTL1_REG_OFFSET 0x10U /*!< CTL1 register offset */ -#define USART_CTL2_REG_OFFSET 0x14U /*!< CTL2 register offset */ -#define USART_CTL3_REG_OFFSET 0x80U /*!< CTL3 register offset */ -#define USART_CHC_REG_OFFSET 0xC0U /*!< CHC register offset */ +#define USART_STAT0_REG_OFFSET 0x00U /*!< STAT0 register offset */ +#define USART_STAT1_REG_OFFSET 0x88U /*!< STAT1 register offset */ +#define USART_CTL0_REG_OFFSET 0x0CU /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x10U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x14U /*!< CTL2 register offset */ +#define USART_CTL3_REG_OFFSET 0x80U /*!< CTL3 register offset */ +#define USART_CHC_REG_OFFSET 0xC0U /*!< CHC register offset */ /* USART flags */ -typedef enum -{ +typedef enum { /* flags in STAT0 register */ USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 9U), /*!< CTS change flag */ USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 8U), /*!< LIN break detected flag */ @@ -192,11 +189,10 @@ typedef enum USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 11U), /*!< receiver timeout flag */ /* flags in CHC register */ USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ -}usart_flag_enum; +} usart_flag_enum; /* USART interrupt flags */ -typedef enum -{ +typedef enum { /* interrupt flags in CTL0 register */ USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT0_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ @@ -214,11 +210,10 @@ typedef enum /* interrupt flags in CTL3 register */ USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 5U, USART_STAT1_REG_OFFSET, 12U), /*!< interrupt enable bit of end of block event and flag */ USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 4U, USART_STAT1_REG_OFFSET, 11U), /*!< interrupt enable bit of receive timeout event and flag */ -}usart_interrupt_flag_enum; +} usart_interrupt_flag_enum; /* USART interrupt flags */ -typedef enum -{ +typedef enum { /* interrupt in CTL0 register */ USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ @@ -233,11 +228,10 @@ typedef enum /* interrupt in CTL3 register */ USART_INT_EB = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 5U), /*!< interrupt enable bit of end of block event */ USART_INT_RT = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 4U), /*!< interrupt enable bit of receive timeout event */ -}usart_interrupt_enum; +} usart_interrupt_enum; -/* USART invert configure */ -typedef enum -{ +/* configure USART invert */ +typedef enum { /* data bit level inversion */ USART_DINV_ENABLE, /*!< data bit level inversion */ USART_DINV_DISABLE, /*!< data bit level not inversion */ @@ -247,14 +241,14 @@ typedef enum /* RX pin level inversion */ USART_RXPIN_ENABLE, /*!< RX pin level inversion */ USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ -}usart_invert_enum; +} usart_invert_enum; -/* USART receiver configure */ +/* configure USART receiver */ #define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) #define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ #define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ -/* USART transmitter configure */ +/* configure USART transmitter */ #define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) #define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ #define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ @@ -307,32 +301,32 @@ typedef enum #define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ #define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ -/* USART DMA request for receive configure */ +/* configure USART DMA request for receive */ #define CLT2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) -#define USART_DENR_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ -#define USART_DENR_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ +#define USART_RECEIVE_DMA_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ +#define USART_RECEIVE_DMA_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ -/* USART DMA request for transmission configure */ +/* configure USART DMA request for transmission */ #define CLT2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) -#define USART_DENT_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ -#define USART_DENT_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ +#define USART_TRANSMIT_DMA_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_TRANSMIT_DMA_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ -/* USART RTS configure */ +/* configure USART RTS */ #define CLT2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) -#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< RTS enable */ -#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< RTS disable */ +#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< enable RTS */ +#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< disable RTS */ -/* USART CTS configure */ +/* configure USART CTS */ #define CLT2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) -#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< CTS enable */ -#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< CTS disable */ +#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< enable CTS */ +#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< disable CTS */ -/* USART one sample bit method configure */ +/* configure USART one sample bit method */ #define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) #define USART_OSB_1bit CTL2_OSB(1) /*!< 1 bit */ #define USART_OSB_3bit CTL2_OSB(0) /*!< 3 bits */ -/* USART IrDA low-power enable */ +/* enable USART IrDA low-power */ #define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) #define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ #define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ @@ -394,7 +388,7 @@ void usart_receiver_timeout_disable(uint32_t usart_periph); /* configure receiver timeout threshold */ void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); /* USART transmit data function */ -void usart_data_transmit(uint32_t usart_periph, uint32_t data); +void usart_data_transmit(uint32_t usart_periph, uint16_t data); /* USART receive data function */ uint16_t usart_data_receive(uint32_t usart_periph); @@ -434,7 +428,7 @@ void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32 /* smartcard communication */ /* configure guard time value in smartcard mode */ -void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +void usart_guard_time_config(uint32_t usart_periph, uint8_t guat); /* enable smartcard mode */ void usart_smartcard_mode_enable(uint32_t usart_periph); /* disable smartcard mode */ @@ -444,9 +438,9 @@ void usart_smartcard_mode_nack_enable(uint32_t usart_periph); /* disable NACK in smartcard mode */ void usart_smartcard_mode_nack_disable(uint32_t usart_periph); /* configure smartcard auto-retry number */ -void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum); /* configure block length */ -void usart_block_length_config(uint32_t usart_periph, uint32_t bl); +void usart_block_length_config(uint32_t usart_periph, uint8_t bl); /* IrDA communication */ /* enable IrDA mode */ @@ -492,4 +486,4 @@ FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_ /* clear interrupt flag in STAT0/STAT1 register */ void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); -#endif /* GD32F4XX_USART_H */ +#endif /* GD32F4XX_USART_H */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h index fa9a5aa..47ca81a 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h @@ -1,14 +1,12 @@ /*! \file gd32f4xx_wwdgt.h \brief definitions for the WWDGT - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -40,7 +38,7 @@ OF SUCH DAMAGE. #include "gd32f4xx.h" /* WWDGT definitions */ -#define WWDGT WWDGT_BASE +#define WWDGT WWDGT_BASE /*!< WWDGT base address */ /* registers definitions */ #define WWDGT_CTL REG32((WWDGT) + 0x00U) /*!< WWDGT control register */ @@ -67,6 +65,11 @@ OF SUCH DAMAGE. #define WWDGT_CFG_PSC_DIV4 CFG_PSC(2) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ #define WWDGT_CFG_PSC_DIV8 CFG_PSC(3) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ +/* write value to WWDGT_CTL_CNT bit field */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) +/* write value to WWDGT_CFG_WIN bit field */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + /* function declarations */ /* reset the window watchdog timer configuration */ void wwdgt_deinit(void); diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c index abc2a50..19267e5 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c @@ -1,64 +1,62 @@ /*! \file gd32f4xx_adc.c \brief ADC driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_adc.h" -#define REGULAR_TRIGGER_MODE ((uint32_t)28U) -#define INSERTED_TRIGGER_MODE ((uint32_t)20U) +#define ROUTINE_TRIGGER_MODE ((uint32_t)28U) +#define INSERTED_TRIGGER_MODE ((uint32_t)20U) /* discontinuous mode macro*/ -#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) +#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) -/* ADC regular channel macro */ -#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U) -#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U) -#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) -#define ADC_REGULAR_CHANNEL_RANK_LENGTH ((uint8_t)5U) +/* ADC routine channel macro */ +#define ADC_ROUTINE_CHANNEL_RANK_SIX ((uint8_t)6U) +#define ADC_ROUTINE_CHANNEL_RANK_TWELVE ((uint8_t)12U) +#define ADC_ROUTINE_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) +#define ADC_ROUTINE_CHANNEL_RANK_LENGTH ((uint8_t)5U) /* ADC sampling time macro */ -#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U) -#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U) -#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U) +#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U) +#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U) +#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U) /* ADC inserted channel macro */ -#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U) -#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U) +#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U) +#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U) /* ADC inserted channel offset macro */ -#define ADC_OFFSET_LENGTH ((uint8_t)3U) -#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) +#define ADC_OFFSET_LENGTH ((uint8_t)3U) +#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) /*! \brief reset ADC @@ -73,9 +71,9 @@ void adc_deinit(void) } /*! - \brief configure the ADC clock for all the ADCs - \param[in] prescaler: configure ADCs prescaler ratio - only one parameter can be selected which is shown as below: + \brief configure the ADC clock for all the ADCs + \param[in] prescaler: configure ADCs prescaler ratio + only one parameter can be selected which is shown as below: \arg ADC_ADCCK_PCLK2_DIV2: PCLK2 div2 \arg ADC_ADCCK_PCLK2_DIV4: PCLK2 div4 \arg ADC_ADCCK_PCLK2_DIV6: PCLK2 div6 @@ -84,8 +82,8 @@ void adc_deinit(void) \arg ADC_ADCCK_HCLK_DIV6: HCLK div6 \arg ADC_ADCCK_HCLK_DIV10: HCLK div10 \arg ADC_ADCCK_HCLK_DIV20: HCLK div20 - \param[out] none - \retval none + \param[out] none + \retval none */ void adc_clock_config(uint32_t prescaler) { @@ -94,88 +92,88 @@ void adc_clock_config(uint32_t prescaler) } /*! - \brief enable or disable ADC special function - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] function: the function to config - only one parameter can be selected which is shown as below: - \arg ADC_SCAN_MODE: scan mode select - \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically - \arg ADC_CONTINUOUS_MODE: continuous mode select - \param[in] newvalue: ENABLE or DISABLE - \param[out] none - \retval none + \brief enable or disable ADC special function + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] function: the function to config + only one parameter can be selected which is shown as below: + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted sequence convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none */ -void adc_special_function_config(uint32_t adc_periph , uint32_t function , ControlStatus newvalue) +void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue) { - if(newvalue){ - if(0U != (function & ADC_SCAN_MODE)){ + if(newvalue) { + if(0U != (function & ADC_SCAN_MODE)) { /* enable scan mode */ ADC_CTL0(adc_periph) |= ADC_SCAN_MODE; } - if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ - /* enable inserted channel group convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* enable inserted sequence convert automatically */ ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO; - } - if(0U != (function & ADC_CONTINUOUS_MODE)){ + } + if(0U != (function & ADC_CONTINUOUS_MODE)) { /* enable continuous mode */ ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE; - } - }else{ - if(0U != (function & ADC_SCAN_MODE)){ + } + } else { + if(0U != (function & ADC_SCAN_MODE)) { /* disable scan mode */ ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE; } - if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ - /* disable inserted channel group convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* disable inserted sequence convert automatically */ ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO; - } - if(0U != (function & ADC_CONTINUOUS_MODE)){ + } + if(0U != (function & ADC_CONTINUOUS_MODE)) { /* disable continuous mode */ ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE; - } + } } } /*! - \brief configure ADC data alignment - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] data_alignment: data alignment select - only one parameter can be selected which is shown as below: - \arg ADC_DATAALIGN_RIGHT: LSB alignment - \arg ADC_DATAALIGN_LEFT: MSB alignment - \param[out] none - \retval none + \brief configure ADC data alignment + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none */ -void adc_data_alignment_config(uint32_t adc_periph , uint32_t data_alignment) +void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment) { - if(ADC_DATAALIGN_RIGHT != data_alignment){ + if(ADC_DATAALIGN_RIGHT != data_alignment) { /* MSB alignment */ ADC_CTL1(adc_periph) |= ADC_CTL1_DAL; - }else{ + } else { /* LSB alignment */ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); } } /*! - \brief enable ADC interface - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief enable ADC interface + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_enable(uint32_t adc_periph) { - if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){ + if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) { /* enable ADC */ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; - } + } } /*! - \brief disable ADC interface - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief disable ADC interface + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_disable(uint32_t adc_periph) { @@ -184,112 +182,112 @@ void adc_disable(uint32_t adc_periph) } /*! - \brief ADC calibration and reset calibration - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief ADC calibration and reset calibration + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_calibration_enable(uint32_t adc_periph) { /* reset the selected ADC calibration registers */ ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB; /* check the RSTCLB bit state */ - while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) { } /* enable ADC calibration process */ ADC_CTL1(adc_periph) |= ADC_CTL1_CLB; /* check the CLB bit state */ - while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) { } } /*! - \brief configure temperature sensor and internal reference voltage channel or VBAT channel function - \param[in] function: temperature sensor and internal reference voltage channel or VBAT channel - only one parameter can be selected which is shown as below: - \arg ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0 - \arg ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0 - \param[in] newvalue: ENABLE or DISABLE -\param[out] none - \retval none + \brief configure temperature sensor and internal reference voltage channel or VBAT channel function + \param[in] function: temperature sensor and internal reference voltage channel or VBAT channel + only one parameter can be selected which is shown as below: + \arg ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0 + \arg ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none */ void adc_channel_16_to_18(uint32_t function, ControlStatus newvalue) { - if(newvalue){ - if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)){ + if(newvalue) { + if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) { /* enable ADC0 Vbat channel */ ADC_SYNCCTL |= ADC_VBAT_CHANNEL_SWITCH; } - if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)){ + if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) { /* enable ADC0 Vref and Temperature channel */ ADC_SYNCCTL |= ADC_TEMP_VREF_CHANNEL_SWITCH; - } - }else{ - if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)){ + } + } else { + if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) { /* disable ADC0 Vbat channel */ ADC_SYNCCTL &= ~ADC_VBAT_CHANNEL_SWITCH; } - if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)){ + if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) { /* disable ADC0 Vref and Temperature channel */ ADC_SYNCCTL &= ~ADC_TEMP_VREF_CHANNEL_SWITCH; - } + } } } /*! - \brief configure ADC resolution - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] resolution: ADC resolution - only one parameter can be selected which is shown as below: - \arg ADC_RESOLUTION_12B: 12-bit ADC resolution - \arg ADC_RESOLUTION_10B: 10-bit ADC resolution - \arg ADC_RESOLUTION_8B: 8-bit ADC resolution - \arg ADC_RESOLUTION_6B: 6-bit ADC resolution - \param[out] none - \retval none + \brief configure ADC resolution + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] resolution: ADC resolution + only one parameter can be selected which is shown as below: + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none */ -void adc_resolution_config(uint32_t adc_periph , uint32_t resolution) +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution) { ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DRES); ADC_CTL0(adc_periph) |= (uint32_t)resolution; } /*! - \brief configure ADC oversample mode - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] mode: ADC oversampling mode - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger - \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger - \param[in] shift: ADC oversampling shift - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift - \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift - \param[in] ratio: ADC oversampling ratio - only one parameter can be selected which is shown as below: - \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 - \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 - \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 - \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 - \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 - \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 - \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 - \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 - \param[out] none - \retval none + \brief configure ADC oversample mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] mode: ADC oversampling mode + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger + \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger + \param[in] shift: ADC oversampling shift + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift + \param[in] ratio: ADC oversampling ratio + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none */ -void adc_oversample_mode_config(uint32_t adc_periph , uint32_t mode , uint16_t shift , uint8_t ratio) +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio) { - if(ADC_OVERSAMPLING_ONE_CONVERT == mode){ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode) { ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS; - }else{ + } else { ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); } /* config the shift and ratio */ @@ -298,10 +296,10 @@ void adc_oversample_mode_config(uint32_t adc_periph , uint32_t mode , uint16_t s } /*! - \brief enable ADC oversample mode - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief enable ADC oversample mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_oversample_mode_enable(uint32_t adc_periph) { @@ -309,10 +307,10 @@ void adc_oversample_mode_enable(uint32_t adc_periph) } /*! - \brief disable ADC oversample mode - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief disable ADC oversample mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_oversample_mode_disable(uint32_t adc_periph) { @@ -320,10 +318,10 @@ void adc_oversample_mode_disable(uint32_t adc_periph) } /*! - \brief enable DMA request - \param[in] adc_periph: ADCx,x=0,1,2 - \param[out] none - \retval none + \brief enable DMA request + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none */ void adc_dma_mode_enable(uint32_t adc_periph) { @@ -332,7 +330,7 @@ void adc_dma_mode_enable(uint32_t adc_periph) } /*! - \brief disable DMA request + \brief disable DMA request \param[in] adc_periph: ADCx,x=0,1,2 \param[out] none \retval none @@ -344,7 +342,7 @@ void adc_dma_mode_disable(uint32_t adc_periph) } /*! - \brief when DMA=1, the DMA engine issues a request at end of each regular conversion + \brief when DMA=1, the DMA engine issues a request at end of each routine conversion \param[in] adc_periph: ADCx,x=0,1,2 \param[out] none \retval none @@ -366,69 +364,69 @@ void adc_dma_request_after_last_disable(uint32_t adc_periph) } /*! - \brief configure ADC discontinuous mode - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: select the channel group - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel - \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 - for regular channel ,the number has no effect for inserted channel - \param[out] none - \retval none + \brief configure ADC discontinuous mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of routine & inserted channel + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for routine sequence ,the number has no effect for inserted sequence + \param[out] none + \retval none */ -void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length) +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_sequence, uint8_t length) { - /* disable discontinuous mode of regular & inserted channel */ - ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC )); - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: + /* disable discontinuous mode of routine & inserted channel */ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: /* config the number of conversions in discontinuous mode */ ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); - if((length <= 8U) && (length >= 1U)){ + if((length <= 8U) && (length >= 1U)) { ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); } - /* enable regular channel group discontinuous mode */ + /* enable routine sequence discontinuous mode */ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; break; case ADC_INSERTED_CHANNEL: - /* enable inserted channel group discontinuous mode */ + /* enable inserted sequence discontinuous mode */ ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; break; case ADC_CHANNEL_DISCON_DISABLE: - /* disable discontinuous mode of regular & inserted channel */ + /* disable discontinuous mode of routine & inserted channel */ default: break; } } /*! - \brief configure the length of regular channel group or inserted channel group - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: select the channel group - only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[in] length: the length of the channel - regular channel 1-16 - inserted channel 1-4 - \param[out] none - \retval none + \brief configure the length of routine sequence or inserted sequence + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] length: the length of the channel + routine channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none */ -void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length) +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length) { - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - if((length >= 1U) && (length <= 16U)){ - ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); - ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length-ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + if((length >= 1U) && (length <= 16U)) { + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); } break; case ADC_INSERTED_CHANNEL: - if((length >= 1U) && (length <= 4U)){ - ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); - ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length-ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + if((length >= 1U) && (length <= 4U)) { + ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); } break; default: @@ -437,149 +435,149 @@ void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , } /*! - \brief configure ADC regular channel - \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 - \param[in] adc_channel: the selected ADC channel - only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x(x=0..18): ADC Channelx - \param[in] sample_time: the sample time value - only one parameter can be selected which is shown as below: - \arg ADC_SAMPLETIME_3: 3 cycles - \arg ADC_SAMPLETIME_15: 15 cycles - \arg ADC_SAMPLETIME_28: 28 cycles - \arg ADC_SAMPLETIME_56: 56 cycles - \arg ADC_SAMPLETIME_84: 84 cycles - \arg ADC_SAMPLETIME_112: 112 cycles - \arg ADC_SAMPLETIME_144: 144 cycles - \arg ADC_SAMPLETIME_480: 480 cycles - \param[out] none - \retval none + \brief configure ADC routine channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the routine sequence rank,this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..18): ADC channelx + \param[in] sample_time: the sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles + \param[out] none + \retval none */ -void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time) +void adc_routine_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) { - uint32_t rsq,sampt; - - /* ADC regular sequence config */ - if(rank < ADC_REGULAR_CHANNEL_RANK_SIX){ - /* the regular group sequence rank is smaller than six */ + uint32_t rsq, sampt; + + /* ADC routine sequence config */ + if(rank < ADC_ROUTINE_CHANNEL_RANK_SIX) { + /* the routine sequence rank is smaller than six */ rsq = ADC_RSQ2(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank)); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank)); ADC_RSQ2(adc_periph) = rsq; - }else if(rank < ADC_REGULAR_CHANNEL_RANK_TWELVE){ - /* the regular group sequence rank is smaller than twelve */ + } else if(rank < ADC_ROUTINE_CHANNEL_RANK_TWELVE) { + /* the routine sequence rank is smaller than twelve */ rsq = ADC_RSQ1(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX)))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX))); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX))); ADC_RSQ1(adc_periph) = rsq; - }else if(rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN){ - /* the regular group sequence rank is smaller than sixteen */ + } else if(rank < ADC_ROUTINE_CHANNEL_RANK_SIXTEEN) { + /* the routine sequence rank is smaller than sixteen */ rsq = ADC_RSQ0(adc_periph); - rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE)))); - /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ - rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE))); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE))); ADC_RSQ0(adc_periph) = rsq; - }else{ + } else { } - + /* ADC sampling time config */ - if(adc_channel < ADC_CHANNEL_SAMPLE_TEN){ - /* the regular group sequence rank is smaller than ten */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the routine sequence rank is smaller than ten */ sampt = ADC_SAMPT1(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel))); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); /* channel sample time set*/ - sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel)); + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)); ADC_SAMPT1(adc_periph) = sampt; - }else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN){ - /* the regular group sequence rank is smaller than eighteen */ + } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) { + /* the routine sequence rank is smaller than eighteen */ sampt = ADC_SAMPT0(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN)))); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); /* channel sample time set*/ - sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel-ADC_CHANNEL_SAMPLE_TEN))); + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); ADC_SAMPT0(adc_periph) = sampt; - }else{ + } else { } } /*! \brief configure ADC inserted channel \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] rank: the inserted sequence rank,this parameter must be between 0 to 3 \param[in] adc_channel: the selected ADC channel only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x(x=0..18): ADC Channelx + \arg ADC_CHANNEL_x(x=0..18): ADC Channelx \param[in] sample_time: The sample time value only one parameter can be selected which is shown as below: - \arg ADC_SAMPLETIME_3: 3 cycles - \arg ADC_SAMPLETIME_15: 15 cycles - \arg ADC_SAMPLETIME_28: 28 cycles - \arg ADC_SAMPLETIME_56: 56 cycles - \arg ADC_SAMPLETIME_84: 84 cycles - \arg ADC_SAMPLETIME_112: 112 cycles - \arg ADC_SAMPLETIME_144: 144 cycles - \arg ADC_SAMPLETIME_480: 480 cycles + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles \param[out] none \retval none */ -void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time) +void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) { uint8_t inserted_length; - uint32_t isq,sampt; + uint32_t isq, sampt; - /* get inserted channel group length */ - inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U); - /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */ - if(rank < 4U){ + /* get inserted sequence length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); + /* the channel number is written to these bits to select a channel as the nth conversion in the inserted sequence */ + if(rank < 4U) { isq = ADC_ISQ(adc_periph); - isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH-(inserted_length-rank)*ADC_INSERTED_CHANNEL_RANK_LENGTH))); - isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH-(inserted_length-rank)*ADC_INSERTED_CHANNEL_RANK_LENGTH)); + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH))); + isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)); ADC_ISQ(adc_periph) = isq; } /* ADC sampling time config */ - if(adc_channel < ADC_CHANNEL_SAMPLE_TEN){ - /* the inserted group sequence rank is smaller than ten */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the inserted sequence rank is smaller than ten */ sampt = ADC_SAMPT1(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel))); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); /* channel sample time set*/ - sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*adc_channel); + sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel); ADC_SAMPT1(adc_periph) = sampt; - }else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN){ - /* the inserted group sequence rank is smaller than eighteen */ + } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) { + /* the inserted sequence rank is smaller than eighteen */ sampt = ADC_SAMPT0(adc_periph); - sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); /* channel sample time set*/ - sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH*(adc_channel - ADC_CHANNEL_SAMPLE_TEN))); + sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); ADC_SAMPT0(adc_periph) = sampt; - }else{ + } else { } } /*! - \brief configure ADC inserted channel offset + \brief configure ADC inserted channel offset \param[in] adc_periph: ADCx,x=0,1,2 \param[in] inserted_channel : insert channel select only one parameter can be selected which is shown as below: - \arg ADC_INSERTED_CHANNEL_0: inserted channel0 - \arg ADC_INSERTED_CHANNEL_1: inserted channel1 - \arg ADC_INSERTED_CHANNEL_2: inserted channel2 - \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 \param[in] offset : the offset data \param[out] none \retval none */ -void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset) +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset) { uint8_t inserted_length; uint32_t num = 0U; - inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph) , 20U , 21U); + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel)); - - if(num <= ADC_OFFSET_LENGTH){ + + if(num <= ADC_OFFSET_LENGTH) { /* calculate the offset of the register */ num = num * ADC_OFFSET_SHIFT_LENGTH; /* config the offset of the selected channels */ @@ -588,62 +586,62 @@ void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_c } /*! - \brief configure ADC external trigger source + \brief configure ADC external trigger source \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: select the channel group + \param[in] adc_sequence: select the sequence only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \param[in] external_trigger_source: regular or inserted group trigger source - for regular channel: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] external_trigger_source: routine or inserted sequence trigger source + for routine sequence: only one parameter can be selected which is shown as below: - \arg ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CC0 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CC1 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CC2 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CC1 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T1_CH2: external trigger timer 1 CC2 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T1_CH3: external trigger timer 1 CC3 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T1_TRGO: external trigger timer 1 TRGO event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T2_CH0 : external trigger timer 2 CC0 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T2_TRGO : external trigger timer 2 TRGO event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T3_CH3: external trigger timer 3 CC3 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T4_CH0: external trigger timer 4 CC0 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T4_CH1: external trigger timer 4 CC1 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T4_CH2: external trigger timer 4 CC2 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T7_CH0: external trigger timer 7 CC0 event select for regular channel - \arg ADC_EXTTRIG_REGULAR_T7_TRGO: external trigger timer 7 TRGO event select for regular channel - \arg ADC_EXTTRIG_REGULAR_EXTI_11: external trigger extiline 11 select for regular channel - for inserted channel: + \arg ADC_EXTTRIG_ROUTINE_T0_CH0: external trigger timer 0 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T0_CH1: external trigger timer 0 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T0_CH2: external trigger timer 0 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH1: external trigger timer 1 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH2: external trigger timer 1 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH3: external trigger timer 1 CC3 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_TRGO: external trigger timer 1 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T2_CH0 : external trigger timer 2 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T2_TRGO : external trigger timer 2 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T3_CH3: external trigger timer 3 CC3 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH0: external trigger timer 4 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH1: external trigger timer 4 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH2: external trigger timer 4 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T7_CH0: external trigger timer 7 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T7_TRGO: external trigger timer 7 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_EXTI_11: external trigger extiline 11 select for routine sequence + for inserted sequence: only one parameter can be selected which is shown as below: - \arg ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3 - \arg ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event - \arg ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0 - \arg ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event - \arg ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1 - \arg ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3 - \arg ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0 - \arg ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1 - \arg ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2 - \arg ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO - \arg ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3 - \arg ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO - \arg ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1 - \arg ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2 - \arg ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3 - \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \arg ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event + \arg ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event + \arg ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 \param[out] none \retval none */ -void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source) -{ - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - /* configure ADC regular group external trigger source */ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t external_trigger_source) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure ADC routine sequence external trigger source */ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; break; case ADC_INSERTED_CHANNEL: - /* configure ADC inserted group external trigger source */ + /* configure ADC inserted sequence external trigger source */ ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; break; @@ -653,58 +651,58 @@ void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channe } /*! - \brief enable ADC external trigger + \brief enable ADC external trigger \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: select the channel group + \param[in] adc_sequence: select the sequence only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence \param[in] trigger_mode: external trigger mode only one parameter can be selected which is shown as below: - \arg EXTERNAL_TRIGGER_DISABLE: external trigger disable - \arg EXTERNAL_TRIGGER_RISING: rising edge of external trigger - \arg EXTERNAL_TRIGGER_FALLING: falling edge of external trigger - \arg EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger + \arg EXTERNAL_TRIGGER_DISABLE: external trigger disable + \arg EXTERNAL_TRIGGER_RISING: rising edge of external trigger + \arg EXTERNAL_TRIGGER_FALLING: falling edge of external trigger + \arg EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger \param[out] none \retval none */ -void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode) +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t trigger_mode) { - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - /* configure ADC regular channel group external trigger mode */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); - ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << REGULAR_TRIGGER_MODE); - break; - case ADC_INSERTED_CHANNEL: - /* configure ADC inserted channel group external trigger mode */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMIC); - ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << INSERTED_TRIGGER_MODE); - break; - default: - break; - } + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure ADC routine sequence external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); + ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << ROUTINE_TRIGGER_MODE); + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted sequence external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMIC); + ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << INSERTED_TRIGGER_MODE); + break; + default: + break; + } } /*! - \brief enable ADC software trigger + \brief enable ADC software trigger \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: select the channel group + \param[in] adc_sequence: select the sequence only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence \param[out] none \retval none */ -void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group) +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_sequence) { - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - /* enable ADC regular channel group software trigger */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* enable ADC routine sequence software trigger */ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; break; case ADC_INSERTED_CHANNEL: - /* enable ADC inserted channel group software trigger */ + /* enable ADC inserted sequence software trigger */ ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST; break; default: @@ -713,60 +711,60 @@ void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group } /*! - \brief configure end of conversion mode + \brief configure end of conversion mode \param[in] adc_periph: ADCx,x=0,1,2 \param[in] end_selection: end of conversion mode only one parameter can be selected which is shown as below: - \arg ADC_EOC_SET_SEQUENCE: only at the end of a sequence of regular conversions, the EOC bit is set.Overflow detection is disabled unless DMA=1. - \arg ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set.Overflow is detected automatically. + \arg ADC_EOC_SET_SEQUENCE: only at the end of a sequence of routine conversions, the EOC bit is set.Overflow detection is disabled unless DMA=1. + \arg ADC_EOC_SET_CONVERSION: at the end of each routine conversion, the EOC bit is set.Overflow is detected automatically. \param[out] none \retval none */ -void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection) +void adc_end_of_conversion_config(uint32_t adc_periph, uint8_t end_selection) { - switch(end_selection){ - case ADC_EOC_SET_SEQUENCE: - /* only at the end of a sequence of regular conversions, the EOC bit is set */ - ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM); - break; - case ADC_EOC_SET_CONVERSION: - /* at the end of each regular conversion, the EOC bit is set.Overflow is detected automatically */ - ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM); - break; - default: - break; + switch(end_selection) { + case ADC_EOC_SET_SEQUENCE: + /* only at the end of a sequence of routine conversions, the EOC bit is set */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM); + break; + case ADC_EOC_SET_CONVERSION: + /* at the end of each routine conversion, the EOC bit is set.Overflow is detected automatically */ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM); + break; + default: + break; } } /*! - \brief read ADC regular group data register + \brief read ADC routine data register \param[in] adc_periph: ADCx,x=0,1,2 \param[in] none \param[out] none \retval the conversion value */ -uint16_t adc_regular_data_read(uint32_t adc_periph) +uint16_t adc_routine_data_read(uint32_t adc_periph) { return (uint16_t)(ADC_RDATA(adc_periph)); } /*! - \brief read ADC inserted group data register + \brief read ADC inserted data register \param[in] adc_periph: ADCx,x=0,1,2 \param[in] inserted_channel : insert channel select only one parameter can be selected which is shown as below: - \arg ADC_INSERTED_CHANNEL_0: inserted Channel0 - \arg ADC_INSERTED_CHANNEL_1: inserted channel1 - \arg ADC_INSERTED_CHANNEL_2: inserted Channel2 - \arg ADC_INSERTED_CHANNEL_3: inserted Channel3 + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 \param[out] none \retval the conversion value */ -uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel) +uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel) { uint32_t idata; /* read the data of the selected channel */ - switch(inserted_channel){ + switch(inserted_channel) { case ADC_INSERTED_CHANNEL_0: /* read the data of channel 0 */ idata = ADC_IDATA0(adc_periph); @@ -791,26 +789,26 @@ uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel) } /*! - \brief disable ADC analog watchdog single channel + \brief disable ADC analog watchdog single channel \param[in] adc_periph: ADCx,x=0,1,2 \param[out] none \retval none */ -void adc_watchdog_single_channel_disable(uint32_t adc_periph ) +void adc_watchdog_single_channel_disable(uint32_t adc_periph) { ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDSC); } /*! - \brief enable ADC analog watchdog single channel + \brief enable ADC analog watchdog single channel \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_channel: the selected ADC channel only one parameter can be selected which is shown as below: - \arg ADC_CHANNEL_x: ADC Channelx(x=0..18) + \arg ADC_CHANNEL_x: ADC Channelx(x=0..18) \param[out] none \retval none */ -void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel) +void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) { ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDCHSEL); @@ -820,31 +818,31 @@ void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channe } /*! - \brief configure ADC analog watchdog group channel + \brief configure ADC analog watchdog sequence channel \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: the channel group use analog watchdog + \param[in] adc_sequence: the sequence use analog watchdog only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_ROUTINE_INSERTED_CHANNEL: both routine and inserted sequence \param[out] none \retval none */ -void adc_watchdog_group_channel_enable(uint32_t adc_periph , uint8_t adc_channel_group) +void adc_watchdog_sequence_channel_enable(uint32_t adc_periph, uint8_t adc_sequence) { ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC)); - /* select the group */ - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - /* regular channel analog watchdog enable */ + /* select the sequence */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* routine channel analog watchdog enable */ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN; break; case ADC_INSERTED_CHANNEL: /* inserted channel analog watchdog enable */ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN; break; - case ADC_REGULAR_INSERTED_CHANNEL: - /* regular and inserted channel analog watchdog enable */ + case ADC_ROUTINE_INSERTED_CHANNEL: + /* routine and inserted channel analog watchdog enable */ ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); break; default: @@ -853,30 +851,30 @@ void adc_watchdog_group_channel_enable(uint32_t adc_periph , uint8_t adc_channel } /*! - \brief disable ADC analog watchdog + \brief disable ADC analog watchdog \param[in] adc_periph: ADCx,x=0,1,2 - \param[in] adc_channel_group: the channel group use analog watchdog + \param[in] adc_sequence: the sequence use analog watchdog only one parameter can be selected which is shown as below: - \arg ADC_REGULAR_CHANNEL: regular channel group - \arg ADC_INSERTED_CHANNEL: inserted channel group - \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_ROUTINE_INSERTED_CHANNEL: both routine and inserted sequence \param[out] none \retval none */ -void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group) +void adc_watchdog_disable(uint32_t adc_periph, uint8_t adc_sequence) { - /* select the group */ - switch(adc_channel_group){ - case ADC_REGULAR_CHANNEL: - /* disable ADC analog watchdog regular channel group */ + /* select the sequence */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* disable ADC analog watchdog routine sequence */ ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_RWDEN); break; case ADC_INSERTED_CHANNEL: - /* disable ADC analog watchdog inserted channel group */ + /* disable ADC analog watchdog inserted sequence */ ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_IWDEN); break; - case ADC_REGULAR_INSERTED_CHANNEL: - /* disable ADC analog watchdog regular and inserted channel group */ + case ADC_ROUTINE_INSERTED_CHANNEL: + /* disable ADC analog watchdog routine and inserted sequence */ ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN)); break; default: @@ -885,14 +883,14 @@ void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group) } /*! - \brief configure ADC analog watchdog threshold + \brief configure ADC analog watchdog threshold \param[in] adc_periph: ADCx,x=0,1,2 \param[in] low_threshold: analog watchdog low threshold,0..4095 \param[in] high_threshold: analog watchdog high threshold,0..4095 \param[out] none \retval none */ -void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold) +void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold) { /* configure ADC analog watchdog low threshold */ ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold); @@ -901,23 +899,23 @@ void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold } /*! - \brief get the ADC flag bits + \brief get the ADC flag bits \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_flag: the adc flag bits only one parameter can be selected which is shown as below: - \arg ADC_FLAG_WDE: analog watchdog event flag - \arg ADC_FLAG_EOC: end of group conversion flag - \arg ADC_FLAG_EOIC: end of inserted group conversion flag - \arg ADC_FLAG_STIC: start flag of inserted channel group - \arg ADC_FLAG_STRC: start flag of regular channel group - \arg ADC_FLAG_ROVF: regular data register overflow flag + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \arg ADC_FLAG_ROVF: routine data register overflow flag \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag) +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag) { FlagStatus reval = RESET; - if(ADC_STAT(adc_periph) & adc_flag){ + if(ADC_STAT(adc_periph) & adc_flag) { reval = SET; } return reval; @@ -925,42 +923,42 @@ FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag) } /*! - \brief clear the ADC flag bits + \brief clear the ADC flag bits \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_flag: the adc flag bits only one parameter can be selected which is shown as below: - \arg ADC_FLAG_WDE: analog watchdog event flag - \arg ADC_FLAG_EOC: end of group conversion flag - \arg ADC_FLAG_EOIC: end of inserted group conversion flag - \arg ADC_FLAG_STIC: start flag of inserted channel group - \arg ADC_FLAG_STRC: start flag of regular channel group - \arg ADC_FLAG_ROVF: regular data register overflow flag + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \arg ADC_FLAG_ROVF: routine data register overflow flag \param[out] none \retval none */ -void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag) +void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); } /*! - \brief get the bit state of ADCx software start conversion + \brief get the bit state of ADCx software start conversion \param[in] adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected \param[in] none \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph) +FlagStatus adc_routine_software_startconv_flag_get(uint32_t adc_periph) { FlagStatus reval = RESET; - if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STRC)){ + if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STRC)) { reval = SET; } return reval; } /*! - \brief get the bit state of ADCx software inserted channel start conversion + \brief get the bit state of ADCx software inserted channel start conversion \param[in] adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected \param[in] none \param[out] none @@ -969,56 +967,56 @@ FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph) FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph) { FlagStatus reval = RESET; - if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STIC)){ + if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STIC)) { reval = SET; } return reval; } /*! - \brief get the ADC interrupt bits + \brief get the ADC interrupt bits \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_interrupt: the adc interrupt bits only one parameter can be selected which is shown as below: - \arg ADC_INT_FLAG_WDE: analog watchdog interrupt - \arg ADC_INT_FLAG_EOC: end of group conversion interrupt - \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt - \arg ADC_INT_FLAG_ROVF: regular data register overflow interrupt + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt + \arg ADC_INT_FLAG_ROVF: routine data register overflow interrupt \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt) +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt) { FlagStatus interrupt_flag = RESET; uint32_t state; /* check the interrupt bits */ - switch(adc_interrupt){ + switch(adc_interrupt) { case ADC_INT_FLAG_WDE: /* get the ADC analog watchdog interrupt bits */ state = ADC_STAT(adc_periph) & ADC_STAT_WDE; - if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state){ - interrupt_flag = SET; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) { + interrupt_flag = SET; } break; case ADC_INT_FLAG_EOC: - /* get the ADC end of group conversion interrupt bits */ + /* get the ADC end of sequence conversion interrupt bits */ state = ADC_STAT(adc_periph) & ADC_STAT_EOC; - if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){ + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) { interrupt_flag = SET; - } + } break; case ADC_INT_FLAG_EOIC: - /* get the ADC end of inserted group conversion interrupt bits */ + /* get the ADC end of inserted sequence conversion interrupt bits */ state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; - if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){ + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) { interrupt_flag = SET; } break; case ADC_INT_FLAG_ROVF: - /* get the ADC regular data register overflow interrupt bits */ + /* get the ADC routine data register overflow interrupt bits */ state = ADC_STAT(adc_periph) & ADC_STAT_ROVF; - if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state){ - interrupt_flag = SET; + if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state) { + interrupt_flag = SET; } break; default: @@ -1028,47 +1026,47 @@ FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt) } /*! - \brief clear the ADC flag + \brief clear the ADC flag \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_interrupt: the adc status flag only one parameter can be selected which is shown as below: - \arg ADC_INT_FLAG_WDE: analog watchdog interrupt - \arg ADC_INT_FLAG_EOC: end of group conversion interrupt - \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt - \arg ADC_INT_FLAG_ROVF: regular data register overflow interrupt + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt + \arg ADC_INT_FLAG_ROVF: routine data register overflow interrupt \param[out] none \retval none */ -void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt) +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt) { ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); } /*! - \brief enable ADC interrupt + \brief enable ADC interrupt \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_interrupt: the adc interrupt flag only one parameter can be selected which is shown as below: - \arg ADC_INT_WDE: analog watchdog interrupt flag - \arg ADC_INT_EOC: end of group conversion interrupt flag - \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag - \arg ADC_INT_ROVF: regular data register overflow interrupt flag + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt flag + \arg ADC_INT_ROVF: routine data register overflow interrupt flag \param[out] none \retval none */ -void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt) +void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt) { - switch(adc_interrupt){ + switch(adc_interrupt) { case ADC_INT_WDE: /* enable analog watchdog interrupt */ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE; break; case ADC_INT_EOC: - /* enable end of group conversion interrupt */ + /* enable end of sequence conversion interrupt */ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE; break; case ADC_INT_EOIC: - /* enable end of inserted group conversion interrupt */ + /* enable end of inserted sequence conversion interrupt */ ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE; break; case ADC_INT_ROVF: @@ -1080,20 +1078,20 @@ void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt) } /*! - \brief disable ADC interrupt + \brief disable ADC interrupt \param[in] adc_periph: ADCx,x=0,1,2 \param[in] adc_flag: the adc interrupt flag only one parameter can be selected which is shown as below: - \arg ADC_INT_WDE: analog watchdog interrupt flag - \arg ADC_INT_EOC: end of group conversion interrupt flag - \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag - \arg ADC_INT_ROVF: regular data register overflow interrupt flag + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt flag + \arg ADC_INT_ROVF: routine data register overflow interrupt flag \param[out] none \retval none */ -void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt) +void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt) { - switch(adc_interrupt){ + switch(adc_interrupt) { /* select the interrupt source */ case ADC_INT_WDE: ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDEIE); @@ -1113,22 +1111,22 @@ void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt) } /*! - \brief configure the ADC sync mode - \param[in] sync_mode: ADC sync mode + \brief configure the ADC sync mode + \param[in] sync_mode: ADC sync mode only one parameter can be selected which is shown as below: - \arg ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently - \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel & inserted parallel mode - \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel & trigger rotation mode - \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode - \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode - \arg ADC_DAUL_REGULAL_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode - \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode - \arg ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined regular parallel & inserted parallel mode - \arg ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION: all ADCs work in combined regular parallel & trigger rotation mode - \arg ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode - \arg ADC_ALL_REGULAL_PARALLEL: all ADCs work in regular parallel mode - \arg ADC_ALL_REGULAL_FOLLOW_UP: all ADCs work in follow-up mode - \arg ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode + \arg ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently + \arg ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined routine parallel & inserted parallel mode + \arg ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined routine parallel & trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode + \arg ADC_DAUL_ROUTINE_PARALLEL: ADC0 and ADC1 work in routine parallel mode + \arg ADC_DAUL_ROUTINE_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode + \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode + \arg ADC_ALL_ROUTINE_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined routine parallel & inserted parallel mode + \arg ADC_ALL_ROUTINE_PARALLEL_INSERTED_ROTATION: all ADCs work in combined routine parallel & trigger rotation mode + \arg ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode + \arg ADC_ALL_ROUTINE_PARALLEL: all ADCs work in routine parallel mode + \arg ADC_ALL_ROUTINE_FOLLOW_UP: all ADCs work in follow-up mode + \arg ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode \param[out] none \retval none */ @@ -1139,10 +1137,10 @@ void adc_sync_mode_config(uint32_t sync_mode) } /*! - \brief configure the delay between 2 sampling phases in ADC sync modes - \param[in] sample_delay: the delay between 2 sampling phases in ADC sync modes + \brief configure the delay between 2 sampling phases in ADC sync modes + \param[in] sample_delay: the delay between 2 sampling phases in ADC sync modes only one parameter can be selected which is shown as below: - \arg ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles + \arg ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles \param[out] none \retval none */ @@ -1153,23 +1151,23 @@ void adc_sync_delay_config(uint32_t sample_delay) } /*! - \brief configure ADC sync DMA mode selection + \brief configure ADC sync DMA mode selection \param[in] dma_mode: ADC sync DMA mode only one parameter can be selected which is shown as below: - \arg ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled - \arg ADC_SYNC_DMA_MODE0: ADC sync DMA mode 0 - \arg ADC_SYNC_DMA_MODE1: ADC sync DMA mode 1 + \arg ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled + \arg ADC_SYNC_DMA_MODE0: ADC sync DMA mode 0 + \arg ADC_SYNC_DMA_MODE1: ADC sync DMA mode 1 \param[out] none \retval none */ -void adc_sync_dma_config(uint32_t dma_mode ) +void adc_sync_dma_config(uint32_t dma_mode) { ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDMA); ADC_SYNCCTL |= dma_mode; } /*! - \brief configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected + \brief configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected \param[in] none \param[out] none \retval none @@ -1180,7 +1178,7 @@ void adc_sync_dma_request_after_last_enable(void) } /*! - \brief configure ADC sync DMA engine issues requests according to the SYNCDMA bits + \brief configure ADC sync DMA engine issues requests according to the SYNCDMA bits \param[in] none \param[out] none \retval none @@ -1191,12 +1189,12 @@ void adc_sync_dma_request_after_last_disable(void) } /*! - \brief read ADC sync regular data register + \brief read ADC sync routine data register \param[in] none \param[out] none - \retval sync regular data + \retval sync routine data */ -uint32_t adc_sync_regular_data_read(void) +uint32_t adc_sync_routine_data_read(void) { return (uint32_t)ADC_SYNCDATA; } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c index 92cab85..fbc8675 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c @@ -1,47 +1,44 @@ /*! \file gd32f4xx_can.c \brief CAN driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2019-11-27, V2.0.1, firmware for GD32F4xx - \version 2020-07-14, V2.0.2, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_can.h" +#include #define CAN_ERROR_HANDLE(s) do{}while(1) /*! - \brief deinitialize CAN + \brief deinitialize CAN \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -59,86 +56,89 @@ void can_deinit(uint32_t can_periph) } /*! - \brief initialize CAN parameter struct with a default value - \param[in] type: the type of CAN parameter struct + \brief initialize CAN parameter struct with a default value + \param[in] type: the type of CAN parameter struct only one parameter can be selected which is shown as below: \arg CAN_INIT_STRUCT: the CAN initial struct \arg CAN_FILTER_STRUCT: the CAN filter struct \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct - \param[in] p_struct: the pointer of the specific struct - \param[out] none + \param[out] p_struct: the pointer of the specific struct \retval none */ -void can_struct_para_init(can_struct_type_enum type, void* p_struct) +void can_struct_para_init(can_struct_type_enum type, void *p_struct) { uint8_t i; - + + if(NULL == p_struct) { + CAN_ERROR_HANDLE("struct parameter can not be NULL \r\n"); + } + /* get type of the struct */ - switch(type){ - /* used for can_init() */ - case CAN_INIT_STRUCT: - ((can_parameter_struct*)p_struct)->auto_bus_off_recovery = DISABLE; - ((can_parameter_struct*)p_struct)->no_auto_retrans = DISABLE; - ((can_parameter_struct*)p_struct)->auto_wake_up = DISABLE; - ((can_parameter_struct*)p_struct)->prescaler = 0x03FFU; - ((can_parameter_struct*)p_struct)->rec_fifo_overwrite = DISABLE; - ((can_parameter_struct*)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ; - ((can_parameter_struct*)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ; - ((can_parameter_struct*)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ; - ((can_parameter_struct*)p_struct)->time_triggered = DISABLE; - ((can_parameter_struct*)p_struct)->trans_fifo_order = DISABLE; - ((can_parameter_struct*)p_struct)->working_mode = CAN_NORMAL_MODE; - - break; - /* used for can_filter_init() */ - case CAN_FILTER_STRUCT: - ((can_filter_parameter_struct*)p_struct)->filter_bits = CAN_FILTERBITS_32BIT; - ((can_filter_parameter_struct*)p_struct)->filter_enable = DISABLE; - ((can_filter_parameter_struct*)p_struct)->filter_fifo_number = CAN_FIFO0; - ((can_filter_parameter_struct*)p_struct)->filter_list_high = 0x0000U; - ((can_filter_parameter_struct*)p_struct)->filter_list_low = 0x0000U; - ((can_filter_parameter_struct*)p_struct)->filter_mask_high = 0x0000U; - ((can_filter_parameter_struct*)p_struct)->filter_mask_low = 0x0000U; - ((can_filter_parameter_struct*)p_struct)->filter_mode = CAN_FILTERMODE_MASK; - ((can_filter_parameter_struct*)p_struct)->filter_number = 0U; - - break; - /* used for can_message_transmit() */ - case CAN_TX_MESSAGE_STRUCT: - for(i = 0U; i < 8U; i++){ - ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U; - } - - ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u; - ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U; - ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD; - ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA; - ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U; - - break; - /* used for can_message_receive() */ - case CAN_RX_MESSAGE_STRUCT: - for(i = 0U; i < 8U; i++){ - ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U; - } - - ((can_receive_message_struct*)p_struct)->rx_dlen = 0U; - ((can_receive_message_struct*)p_struct)->rx_efid = 0U; - ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD; - ((can_receive_message_struct*)p_struct)->rx_fi = 0U; - ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA; - ((can_receive_message_struct*)p_struct)->rx_sfid = 0U; - - break; - - default: - CAN_ERROR_HANDLE("parameter is invalid \r\n"); + switch(type) { + /* used for can_init() */ + case CAN_INIT_STRUCT: + ((can_parameter_struct *)p_struct)->auto_bus_off_recovery = DISABLE; + ((can_parameter_struct *)p_struct)->auto_retrans = DISABLE; + ((can_parameter_struct *)p_struct)->auto_wake_up = DISABLE; + ((can_parameter_struct *)p_struct)->prescaler = 0x03FFU; + ((can_parameter_struct *)p_struct)->rec_fifo_overwrite = DISABLE; + ((can_parameter_struct *)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ; + ((can_parameter_struct *)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ; + ((can_parameter_struct *)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ; + ((can_parameter_struct *)p_struct)->time_triggered = DISABLE; + ((can_parameter_struct *)p_struct)->trans_fifo_order = DISABLE; + ((can_parameter_struct *)p_struct)->working_mode = CAN_NORMAL_MODE; + + break; + /* used for can_filter_init() */ + case CAN_FILTER_STRUCT: + ((can_filter_parameter_struct *)p_struct)->filter_bits = CAN_FILTERBITS_32BIT; + ((can_filter_parameter_struct *)p_struct)->filter_enable = DISABLE; + ((can_filter_parameter_struct *)p_struct)->filter_fifo_number = CAN_FIFO0; + ((can_filter_parameter_struct *)p_struct)->filter_list_high = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_list_low = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mask_high = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mask_low = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mode = CAN_FILTERMODE_MASK; + ((can_filter_parameter_struct *)p_struct)->filter_number = 0U; + + break; + /* used for can_message_transmit() */ + case CAN_TX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++) { + ((can_trasnmit_message_struct *)p_struct)->tx_data[i] = 0U; + } + + ((can_trasnmit_message_struct *)p_struct)->tx_dlen = 0u; + ((can_trasnmit_message_struct *)p_struct)->tx_efid = 0U; + ((can_trasnmit_message_struct *)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_trasnmit_message_struct *)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA; + ((can_trasnmit_message_struct *)p_struct)->tx_sfid = 0U; + + break; + /* used for can_message_receive() */ + case CAN_RX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++) { + ((can_receive_message_struct *)p_struct)->rx_data[i] = 0U; + } + + ((can_receive_message_struct *)p_struct)->rx_dlen = 0U; + ((can_receive_message_struct *)p_struct)->rx_efid = 0U; + ((can_receive_message_struct *)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_receive_message_struct *)p_struct)->rx_fi = 0U; + ((can_receive_message_struct *)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA; + ((can_receive_message_struct *)p_struct)->rx_sfid = 0U; + + break; + + default: + CAN_ERROR_HANDLE("parameter is invalid \r\n"); } } /*! - \brief initialize CAN + \brief initialize CAN \param[in] can_periph \arg CANx(x=0,1) \param[in] can_parameter_init: parameters for CAN initializtion @@ -149,30 +149,30 @@ void can_struct_para_init(can_struct_type_enum type, void* p_struct) \arg time_triggered: ENABLE or DISABLE \arg auto_bus_off_recovery: ENABLE or DISABLE \arg auto_wake_up: ENABLE or DISABLE - \arg no_auto_retrans: ENABLE or DISABLE + \arg auto_retrans: ENABLE or DISABLE \arg rec_fifo_overwrite: ENABLE or DISABLE \arg trans_fifo_order: ENABLE or DISABLE \arg prescaler: 0x0001 - 0x0400 \param[out] none \retval ErrStatus: SUCCESS or ERROR */ -ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init) { uint32_t timeout = CAN_TIMEOUT; ErrStatus flag = ERROR; - + /* disable sleep mode */ CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; /* enable initialize mode */ CAN_CTL(can_periph) |= CAN_CTL_IWMOD; /* wait ACK */ - while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { timeout--; } /* check initialize working success */ - if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) { flag = ERROR; - }else{ + } else { /* set the bit timing register */ CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ @@ -181,138 +181,138 @@ ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); /* time trigger communication mode */ - if(ENABLE == can_parameter_init->time_triggered){ + if(ENABLE == can_parameter_init->time_triggered) { CAN_CTL(can_periph) |= CAN_CTL_TTC; - }else{ + } else { CAN_CTL(can_periph) &= ~CAN_CTL_TTC; } - /* automatic bus-off managment */ - if(ENABLE == can_parameter_init->auto_bus_off_recovery){ + /* automatic bus-off management */ + if(ENABLE == can_parameter_init->auto_bus_off_recovery) { CAN_CTL(can_periph) |= CAN_CTL_ABOR; - }else{ + } else { CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; } /* automatic wakeup mode */ - if(ENABLE == can_parameter_init->auto_wake_up){ + if(ENABLE == can_parameter_init->auto_wake_up) { CAN_CTL(can_periph) |= CAN_CTL_AWU; - }else{ + } else { CAN_CTL(can_periph) &= ~CAN_CTL_AWU; } - /* automatic retransmission mode disable*/ - if(ENABLE == can_parameter_init->no_auto_retrans){ - CAN_CTL(can_periph) |= CAN_CTL_ARD; - }else{ + /* automatic retransmission mode */ + if(ENABLE == can_parameter_init->auto_retrans) { CAN_CTL(can_periph) &= ~CAN_CTL_ARD; + } else { + CAN_CTL(can_periph) |= CAN_CTL_ARD; } - /* receive fifo overwrite mode */ - if(ENABLE == can_parameter_init->rec_fifo_overwrite){ - CAN_CTL(can_periph) |= CAN_CTL_RFOD; - }else{ + /* receive FIFO overwrite mode */ + if(ENABLE == can_parameter_init->rec_fifo_overwrite) { CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; - } - /* transmit fifo order */ - if(ENABLE == can_parameter_init->trans_fifo_order){ + } else { + CAN_CTL(can_periph) |= CAN_CTL_RFOD; + } + /* transmit FIFO order */ + if(ENABLE == can_parameter_init->trans_fifo_order) { CAN_CTL(can_periph) |= CAN_CTL_TFO; - }else{ + } else { CAN_CTL(can_periph) &= ~CAN_CTL_TFO; - } + } /* disable initialize mode */ CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; timeout = CAN_TIMEOUT; /* wait the ACK */ - while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { timeout--; } /* check exit initialize mode */ - if(0U != timeout){ + if(0U != timeout) { flag = SUCCESS; } - } + } return flag; } /*! - \brief initialize CAN filter + \brief initialize CAN filter \param[in] can_filter_parameter_init: struct for CAN filter initialization \arg filter_list_high: 0x0000 - 0xFFFF \arg filter_list_low: 0x0000 - 0xFFFF \arg filter_mask_high: 0x0000 - 0xFFFF \arg filter_mask_low: 0x0000 - 0xFFFF - \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 \arg filter_number: 0 - 27 \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST - \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT \arg filter_enable: ENABLE or DISABLE \param[out] none \retval none */ -void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init) +void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init) { uint32_t val = 0U; - + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); /* filter lock disable */ CAN_FCTL(CAN0) |= CAN_FCTL_FLD; /* disable filter */ CAN_FW(CAN0) &= ~(uint32_t)val; - + /* filter 16 bits */ - if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits) { /* set filter 16 bits */ CAN_FSCFG(CAN0) &= ~(uint32_t)val; /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ - FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ - FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ - FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ - FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); } /* filter 32 bits */ - if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits) { /* set filter 32 bits */ CAN_FSCFG(CAN0) |= (uint32_t)val; /* 32 bits list or first 32 bits list */ CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ - FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | - FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); /* 32 bits mask or second 32 bits list */ CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ - FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | - FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); } - + /* filter mode */ - if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode) { /* mask mode */ CAN_FMCFG(CAN0) &= ~(uint32_t)val; - }else{ + } else { /* list mode */ CAN_FMCFG(CAN0) |= (uint32_t)val; } - + /* filter FIFO */ - if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)) { /* FIFO0 */ CAN_FAFIFO(CAN0) &= ~(uint32_t)val; - }else{ + } else { /* FIFO1 */ CAN_FAFIFO(CAN0) |= (uint32_t)val; } - + /* filter working */ - if(ENABLE == can_filter_parameter_init->filter_enable){ - + if(ENABLE == can_filter_parameter_init->filter_enable) { + CAN_FW(CAN0) |= (uint32_t)val; } - + /* filter lock enable */ CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; } /*! - \brief set CAN1 fliter start bank number + \brief set CAN1 filter start bank number \param[in] start_bank: CAN1 start bank number only one parameter can be selected which is shown as below: \arg (1..27) @@ -326,12 +326,12 @@ void can1_filter_start_bank(uint8_t start_bank) /* set CAN1 filter start number */ CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); - /* filter lock enaable */ + /* filter lock enable */ CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; } /*! - \brief enable CAN debug freeze + \brief enable CAN debug freeze \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -341,7 +341,8 @@ void can_debug_freeze_enable(uint32_t can_periph) { /* set DFZ bit */ CAN_CTL(can_periph) |= CAN_CTL_DFZ; - if(CAN0 == can_periph){ + + if(CAN0 == can_periph) { dbg_periph_enable(DBG_CAN0_HOLD); }else{ dbg_periph_enable(DBG_CAN1_HOLD); @@ -349,7 +350,7 @@ void can_debug_freeze_enable(uint32_t can_periph) } /*! - \brief disable CAN debug freeze + \brief disable CAN debug freeze \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -359,6 +360,7 @@ void can_debug_freeze_disable(uint32_t can_periph) { /* set DFZ bit */ CAN_CTL(can_periph) &= ~CAN_CTL_DFZ; + if(CAN0 == can_periph){ dbg_periph_disable(DBG_CAN0_HOLD); }else{ @@ -367,7 +369,7 @@ void can_debug_freeze_disable(uint32_t can_periph) } /*! - \brief enable CAN time trigger mode + \brief enable CAN time trigger mode \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -376,17 +378,17 @@ void can_debug_freeze_disable(uint32_t can_periph) void can_time_trigger_mode_enable(uint32_t can_periph) { uint8_t mailbox_number; - - /* enable the tcc mode */ + + /* enable the TTC mode */ CAN_CTL(can_periph) |= CAN_CTL_TTC; /* enable time stamp */ - for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) { CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; } } /*! - \brief disable CAN time trigger mode + \brief disable CAN time trigger mode \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -394,18 +396,18 @@ void can_time_trigger_mode_enable(uint32_t can_periph) */ void can_time_trigger_mode_disable(uint32_t can_periph) { - uint8_t mailbox_number; - - /* disable the TCC mode */ + uint8_t mailbox_number; + + /* disable the TTC mode */ CAN_CTL(can_periph) &= ~CAN_CTL_TTC; /* reset TSEN bits */ - for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) { CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; } } /*! - \brief transmit CAN message + \brief transmit CAN message \param[in] can_periph \arg CANx(x=0,1) \param[in] transmit_message: struct for CAN transmit message @@ -418,48 +420,48 @@ void can_time_trigger_mode_disable(uint32_t can_periph) \param[out] none \retval mailbox_number */ -uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message) +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message) { uint8_t mailbox_number = CAN_MAILBOX0; /* select one empty mailbox */ - if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){ + if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) { mailbox_number = CAN_MAILBOX0; - }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){ + } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) { mailbox_number = CAN_MAILBOX1; - }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){ + } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) { mailbox_number = CAN_MAILBOX2; - }else{ + } else { mailbox_number = CAN_NOMAILBOX; } /* return no mailbox empty */ - if(CAN_NOMAILBOX == mailbox_number){ + if(CAN_NOMAILBOX == mailbox_number) { return CAN_NOMAILBOX; } - + CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN; - if(CAN_FF_STANDARD == transmit_message->tx_ff){ + if(CAN_FF_STANDARD == transmit_message->tx_ff) { /* set transmit mailbox standard identifier */ CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \ - transmit_message->tx_ft); - }else{ + transmit_message->tx_ft); + } else { /* set transmit mailbox extended identifier */ CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \ - transmit_message->tx_ff | \ - transmit_message->tx_ft); + transmit_message->tx_ff | \ + transmit_message->tx_ft); } /* set the data length */ CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC; CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; /* set the data */ CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ - TMDATA0_DB2(transmit_message->tx_data[2]) | \ - TMDATA0_DB1(transmit_message->tx_data[1]) | \ - TMDATA0_DB0(transmit_message->tx_data[0]); + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ - TMDATA1_DB6(transmit_message->tx_data[6]) | \ - TMDATA1_DB5(transmit_message->tx_data[5]) | \ - TMDATA1_DB4(transmit_message->tx_data[4]); + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); /* enable transmission */ CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; @@ -467,7 +469,7 @@ uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* t } /*! - \brief get CAN transmit state + \brief get CAN transmit state \param[in] can_periph \arg CANx(x=0,1) \param[in] mailbox_number @@ -480,9 +482,9 @@ can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox { can_transmit_state_enum state = CAN_TRANSMIT_FAILED; uint32_t val = 0U; - - /* check selected mailbox state */ - switch(mailbox_number){ + + /* check selected mailbox state */ + switch(mailbox_number) { /* mailbox0 */ case CAN_MAILBOX0: val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0); @@ -499,26 +501,26 @@ can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox val = CAN_TRANSMIT_FAILED; break; } - - switch(val){ - /* transmit pending */ - case (CAN_STATE_PENDING): + + switch(val) { + /* transmit pending */ + case(CAN_STATE_PENDING): state = CAN_TRANSMIT_PENDING; break; - /* mailbox0 transmit succeeded */ - case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + /* mailbox0 transmit succeeded */ + case(CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): state = CAN_TRANSMIT_OK; break; - /* mailbox1 transmit succeeded */ - case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): + /* mailbox1 transmit succeeded */ + case(CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): state = CAN_TRANSMIT_OK; break; - /* mailbox2 transmit succeeded */ - case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): + /* mailbox2 transmit succeeded */ + case(CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): state = CAN_TRANSMIT_OK; break; - /* transmit failed */ - default: + /* transmit failed */ + default: state = CAN_TRANSMIT_FAILED; break; } @@ -526,7 +528,7 @@ can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox } /*! - \brief stop CAN transmission + \brief stop CAN transmission \param[in] can_periph \arg CANx(x=0,1) \param[in] mailbox_number @@ -537,25 +539,25 @@ can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox */ void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) { - if(CAN_MAILBOX0 == mailbox_number){ + if(CAN_MAILBOX0 == mailbox_number) { CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0; - while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){ + while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) { } - }else if(CAN_MAILBOX1 == mailbox_number){ + } else if(CAN_MAILBOX1 == mailbox_number) { CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1; - while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){ + while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) { } - }else if(CAN_MAILBOX2 == mailbox_number){ + } else if(CAN_MAILBOX2 == mailbox_number) { CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2; - while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){ + while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) { } - }else{ + } else { /* illegal parameters */ } } /*! - \brief CAN receive message + \brief CAN receive message \param[in] can_periph \arg CANx(x=0,1) \param[in] fifo_number @@ -570,25 +572,25 @@ void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) \arg rx_fi: 0 - 27 \retval none */ -void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message) +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message) { /* get the frame format */ receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number)); - if(CAN_FF_STANDARD == receive_message->rx_ff){ + if(CAN_FF_STANDARD == receive_message->rx_ff) { /* get standard identifier */ receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number))); - }else{ + } else { /* get extended identifier */ receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number))); } - + /* get frame type */ - receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); + receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); /* filtering index */ receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number))); - /* get recevie data length */ + /* get receive data length */ receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number))); - + /* receive data */ receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number))); receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number))); @@ -598,17 +600,17 @@ void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_m receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number))); receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number))); receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); - + /* release FIFO */ - if(CAN_FIFO0 == fifo_number){ + if(CAN_FIFO0 == fifo_number) { CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; - }else{ + } else { CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; } } /*! - \brief release FIFO0 + \brief release FIFO \param[in] can_periph \arg CANx(x=0,1) \param[in] fifo_number @@ -619,44 +621,44 @@ void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_m */ void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) { - if(CAN_FIFO0 == fifo_number){ + if(CAN_FIFO0 == fifo_number) { CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; - }else if(CAN_FIFO1 == fifo_number){ + } else if(CAN_FIFO1 == fifo_number) { CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; - }else{ + } else { /* illegal parameters */ CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n"); } } /*! - \brief CAN receive message length + \brief CAN receive message length \param[in] can_periph \arg CANx(x=0,1) \param[in] fifo_number only one parameter can be selected which is shown as below: - \arg CAN_FIFOx(x=0,1) + \arg CAN_FIFOx(x=0,1) \param[out] none \retval message length */ uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) { uint8_t val = 0U; - - if(CAN_FIFO0 == fifo_number){ + + if(CAN_FIFO0 == fifo_number) { /* FIFO0 */ val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK); - }else if(CAN_FIFO1 == fifo_number){ + } else if(CAN_FIFO1 == fifo_number) { /* FIFO1 */ val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK); - }else{ + } else { /* illegal parameters */ } return val; } /*! - \brief set CAN working mode + \brief set CAN working mode \param[in] can_periph \arg CANx(x=0,1) \param[in] can_working_mode @@ -671,56 +673,56 @@ ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) { ErrStatus flag = ERROR; /* timeout for IWS or also for SLPWS bits */ - uint32_t timeout = CAN_TIMEOUT; - - if(CAN_MODE_INITIALIZE == working_mode){ + uint32_t timeout = CAN_TIMEOUT; + + if(CAN_MODE_INITIALIZE == working_mode) { /* disable sleep mode */ CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD); /* set initialize mode */ CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD; /* wait the acknowledge */ - while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { timeout--; } - if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) { flag = ERROR; - }else{ + } else { flag = SUCCESS; } - }else if(CAN_MODE_NORMAL == working_mode){ + } else if(CAN_MODE_NORMAL == working_mode) { /* enter normal mode */ CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD); /* wait the acknowledge */ - while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){ + while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)) { timeout--; } - if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){ + if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) { flag = ERROR; - }else{ + } else { flag = SUCCESS; } - }else if(CAN_MODE_SLEEP == working_mode){ + } else if(CAN_MODE_SLEEP == working_mode) { /* disable initialize mode */ CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD); /* set sleep mode */ CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD; /* wait the acknowledge */ - while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){ + while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)) { timeout--; } - if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) { flag = ERROR; - }else{ + } else { flag = SUCCESS; } - }else{ + } else { flag = ERROR; } return flag; } /*! - \brief wake up CAN + \brief wake up CAN \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -730,24 +732,24 @@ ErrStatus can_wakeup(uint32_t can_periph) { ErrStatus flag = ERROR; uint32_t timeout = CAN_TIMEOUT; - + /* wakeup */ CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; - - while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){ + + while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)) { timeout--; } /* check state */ - if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){ + if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) { flag = ERROR; - }else{ + } else { flag = SUCCESS; } return flag; } /*! - \brief get CAN error type + \brief get CAN error type \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -765,14 +767,14 @@ can_error_enum can_error_get(uint32_t can_periph) { can_error_enum error; error = CAN_ERROR_NONE; - + /* get error type */ error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph))); return error; } /*! - \brief get CAN receive error number + \brief get CAN receive error number \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -781,14 +783,14 @@ can_error_enum can_error_get(uint32_t can_periph) uint8_t can_receive_error_number_get(uint32_t can_periph) { uint8_t val; - + /* get error count */ val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph))); return val; } /*! - \brief get CAN transmit error number + \brief get CAN transmit error number \param[in] can_periph \arg CANx(x=0,1) \param[out] none @@ -797,69 +799,13 @@ uint8_t can_receive_error_number_get(uint32_t can_periph) uint8_t can_transmit_error_number_get(uint32_t can_periph) { uint8_t val; - + val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph))); return val; } /*! - \brief enable CAN interrupt - \param[in] can_periph - \arg CANx(x=0,1) - \param[in] interrupt - one or more parameters can be selected which are shown as below: - \arg CAN_INT_TME: transmit mailbox empty interrupt enable - \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable - \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable - \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable - \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable - \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable - \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable - \arg CAN_INT_WERR: warning error interrupt enable - \arg CAN_INT_PERR: passive error interrupt enable - \arg CAN_INT_BO: bus-off interrupt enable - \arg CAN_INT_ERRN: error number interrupt enable - \arg CAN_INT_ERR: error interrupt enable - \arg CAN_INT_WU: wakeup interrupt enable - \arg CAN_INT_SLPW: sleep working interrupt enable - \param[out] none - \retval none -*/ -void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) -{ - CAN_INTEN(can_periph) |= interrupt; -} - -/*! - \brief disable CAN interrupt - \param[in] can_periph - \arg CANx(x=0,1) - \param[in] interrupt - one or more parameters can be selected which are shown as below: - \arg CAN_INT_TME: transmit mailbox empty interrupt enable - \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable - \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable - \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable - \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable - \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable - \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable - \arg CAN_INT_WERR: warning error interrupt enable - \arg CAN_INT_PERR: passive error interrupt enable - \arg CAN_INT_BO: bus-off interrupt enable - \arg CAN_INT_ERRN: error number interrupt enable - \arg CAN_INT_ERR: error interrupt enable - \arg CAN_INT_WU: wakeup interrupt enable - \arg CAN_INT_SLPW: sleep working interrupt enable - \param[out] none - \retval none -*/ -void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) -{ - CAN_INTEN(can_periph) &= ~interrupt; -} - -/*! - \brief get CAN flag state + \brief get CAN flag state \param[in] can_periph \arg CANx(x=0,1) \param[in] flag: CAN flags, refer to can_flag_enum @@ -873,9 +819,9 @@ void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) \arg CAN_FLAG_ERRIF: error flag \arg CAN_FLAG_SLPWS: sleep working state \arg CAN_FLAG_IWS: initial working state - \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in Tx FIFO - \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in Tx FIFO - \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in Tx FIFO + \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in TX FIFO + \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in TX FIFO + \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in TX FIFO \arg CAN_FLAG_TME2: transmit mailbox 2 empty \arg CAN_FLAG_TME1: transmit mailbox 1 empty \arg CAN_FLAG_TME0: transmit mailbox 0 empty @@ -902,17 +848,17 @@ void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) \retval FlagStatus: SET or RESET */ FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) -{ +{ /* get flag and interrupt enable state */ - if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){ + if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear CAN flag state + \brief clear CAN flag state \param[in] can_periph \arg CANx(x=0,1) \param[in] flag: CAN flags, refer to can_flag_enum @@ -945,7 +891,63 @@ void can_flag_clear(uint32_t can_periph, can_flag_enum flag) } /*! - \brief get CAN interrupt flag state + \brief enable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WAKEUP: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) |= interrupt; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WAKEUP: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) &= ~interrupt; +} + +/*! + \brief get CAN interrupt flag state \param[in] can_periph \arg CANx(x=0,1) \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum @@ -973,29 +975,29 @@ FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum f { uint32_t ret1 = RESET; uint32_t ret2 = RESET; - - /* get the staus of interrupt flag */ - if (flag == CAN_INT_FLAG_RFF0) { + + /* get the status of interrupt flag */ + if(flag == CAN_INT_FLAG_RFL0) { ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0); - } else if (flag == CAN_INT_FLAG_RFF1) { + } else if(flag == CAN_INT_FLAG_RFL1) { ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1); - } else if (flag == CAN_INT_FLAG_ERRN) { + } else if(flag == CAN_INT_FLAG_ERRN) { ret1 = can_error_get(can_periph); } else { ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag)); } - /* get the staus of interrupt enale bit */ + /* get the status of interrupt enable bit */ ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag)); - if(ret1 && ret2){ + if(ret1 && ret2) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear CAN interrupt flag state - \param[in] can_periph + \brief clear CAN interrupt flag state + \param[in] can_periph \arg CANx(x=0,1) \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum only one parameter can be selected which is shown as below: diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c index 2e369e7..b0cf588 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c @@ -2,35 +2,33 @@ \file gd32f4xx_crc.c \brief CRC driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -38,8 +36,9 @@ OF SUCH DAMAGE. #define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) #define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U) + /*! - \brief deinit CRC calculation unit + \brief deinit CRC calculation unit \param[in] none \param[out] none \retval none @@ -52,7 +51,7 @@ void crc_deinit(void) } /*! - \brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF + \brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF \param[in] none \param[out] none \retval none @@ -63,7 +62,7 @@ void crc_data_register_reset(void) } /*! - \brief read the value of the data register + \brief read the value of the data register \param[in] none \param[out] none \retval 32-bit value of the data register @@ -76,7 +75,7 @@ uint32_t crc_data_register_read(void) } /*! - \brief read the value of the free data register + \brief read the value of the free data register \param[in] none \param[out] none \retval 8-bit value of the free data register @@ -89,7 +88,7 @@ uint8_t crc_free_data_register_read(void) } /*! - \brief write data to the free data register + \brief write data to the free data register \param[in] free_data: specified 8-bit data \param[out] none \retval none @@ -100,7 +99,7 @@ void crc_free_data_register_write(uint8_t free_data) } /*! - \brief calculate the CRC value of a 32-bit data + \brief calculate the CRC value of a 32-bit data \param[in] sdata: specified 32-bit data \param[out] none \retval 32-bit value calculated by CRC @@ -112,7 +111,7 @@ uint32_t crc_single_data_calculate(uint32_t sdata) } /*! - \brief calculate the CRC value of an array of 32-bit values + \brief calculate the CRC value of an array of 32-bit values \param[in] array: pointer to an array of 32-bit values \param[in] size: size of the array \param[out] none @@ -121,7 +120,7 @@ uint32_t crc_single_data_calculate(uint32_t sdata) uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) { uint32_t index; - for(index = 0U; index < size; index++){ + for(index = 0U; index < size; index++) { CRC_DATA = array[index]; } return (CRC_DATA); diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c index 1ad9e01..9492d95 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c @@ -2,35 +2,33 @@ \file gd32f4xx_ctc.c \brief CTC driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -135,27 +133,12 @@ void ctc_refsource_polarity_config(uint32_t polarity) CTC_CTL1 |= (uint32_t)polarity; } -/*! - \brief select USBFS or USBHS SOF signal - \param[in] usbsof: - \arg CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected - \arg CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected - \param[out] none - \retval none -*/ -void ctc_usbsof_signal_select(uint32_t usbsof) -{ - CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL); - CTC_CTL1 |= (uint32_t)usbsof; -} - /*! \brief select reference signal source \param[in] refs: only one parameter can be selected which is shown as below: \arg CTC_REFSOURCE_GPIO: GPIO is selected \arg CTC_REFSOURCE_LXTAL: LXTAL is selected - \arg CTC_REFSOURCE_USBSOF: USBSOF is selected \param[out] none \retval none */ @@ -221,7 +204,7 @@ void ctc_counter_reload_value_config(uint16_t reload_value) uint16_t ctc_counter_capture_value_read(void) { uint16_t capture_value = 0U; - capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> CTC_REFCAP_OFFSET); + capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP) >> CTC_REFCAP_OFFSET); return (capture_value); } @@ -235,9 +218,9 @@ uint16_t ctc_counter_capture_value_read(void) */ FlagStatus ctc_counter_direction_read(void) { - if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){ + if(RESET != (CTC_STAT & CTC_STAT_REFDIR)) { return SET; - }else{ + } else { return RESET; } } @@ -281,7 +264,7 @@ uint8_t ctc_irc48m_trim_value_read(void) */ void ctc_interrupt_enable(uint32_t interrupt) { - CTC_CTL0 |= (uint32_t)interrupt; + CTC_CTL0 |= (uint32_t)interrupt; } /*! @@ -297,7 +280,7 @@ void ctc_interrupt_enable(uint32_t interrupt) */ void ctc_interrupt_disable(uint32_t interrupt) { - CTC_CTL0 &= (uint32_t)(~interrupt); + CTC_CTL0 &= (uint32_t)(~interrupt); } /*! @@ -305,11 +288,11 @@ void ctc_interrupt_disable(uint32_t interrupt) \param[in] int_flag: the CTC interrupt flag only one parameter can be selected which is shown as below: \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt - \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt - \arg CTC_INT_FLAG_ERR: error interrupt + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt + \arg CTC_INT_FLAG_ERR: error interrupt \arg CTC_INT_FLAG_EREF: expect reference interrupt \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt - \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt \param[out] none \retval FlagStatus: SET or RESET @@ -317,20 +300,20 @@ void ctc_interrupt_disable(uint32_t interrupt) FlagStatus ctc_interrupt_flag_get(uint32_t int_flag) { uint32_t interrupt_flag = 0U, intenable = 0U; - + /* check whether the interrupt is enabled */ - if(RESET != (int_flag & CTC_FLAG_MASK)){ + if(RESET != (int_flag & CTC_FLAG_MASK)) { intenable = CTC_CTL0 & CTC_CTL0_ERRIE; - }else{ + } else { intenable = CTC_CTL0 & int_flag; } - + /* get interrupt flag status */ interrupt_flag = CTC_STAT & int_flag; - if(interrupt_flag && intenable){ + if(interrupt_flag && intenable) { return SET; - }else{ + } else { return RESET; } } @@ -340,20 +323,20 @@ FlagStatus ctc_interrupt_flag_get(uint32_t int_flag) \param[in] int_flag: the CTC interrupt flag only one parameter can be selected which is shown as below: \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt - \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt - \arg CTC_INT_FLAG_ERR: error interrupt - \arg CTC_INT_FLAG_EREF: expect reference interrupt + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt + \arg CTC_INT_FLAG_ERR: error interrupt + \arg CTC_INT_FLAG_EREF: expect reference interrupt \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt - \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt \param[out] none \retval none -*/ +*/ void ctc_interrupt_flag_clear(uint32_t int_flag) { - if(RESET != (int_flag & CTC_FLAG_MASK)){ + if(RESET != (int_flag & CTC_FLAG_MASK)) { CTC_INTC |= CTC_INTC_ERRIC; - }else{ + } else { CTC_INTC |= int_flag; } } @@ -361,10 +344,10 @@ void ctc_interrupt_flag_clear(uint32_t int_flag) /*! \brief get CTC flag \param[in] flag: the CTC flag - only one parameter can be selected which is shown as below: + only one parameter can be selected which is shown as below: \arg CTC_FLAG_CKOK: clock trim OK flag - \arg CTC_FLAG_CKWARN: clock trim warning flag - \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag \arg CTC_FLAG_EREF: expect reference flag \arg CTC_FLAG_CKERR: clock trim error bit \arg CTC_FLAG_REFMISS: reference sync pulse miss @@ -374,9 +357,9 @@ void ctc_interrupt_flag_clear(uint32_t int_flag) */ FlagStatus ctc_flag_get(uint32_t flag) { - if(RESET != (CTC_STAT & flag)){ + if(RESET != (CTC_STAT & flag)) { return SET; - }else{ + } else { return RESET; } } @@ -386,8 +369,8 @@ FlagStatus ctc_flag_get(uint32_t flag) \param[in] flag: the CTC flag only one parameter can be selected which is shown as below: \arg CTC_FLAG_CKOK: clock trim OK flag - \arg CTC_FLAG_CKWARN: clock trim warning flag - \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag \arg CTC_FLAG_EREF: expect reference flag \arg CTC_FLAG_CKERR: clock trim error bit \arg CTC_FLAG_REFMISS: reference sync pulse miss @@ -397,9 +380,9 @@ FlagStatus ctc_flag_get(uint32_t flag) */ void ctc_flag_clear(uint32_t flag) { - if(RESET != (flag & CTC_FLAG_MASK)){ + if(RESET != (flag & CTC_FLAG_MASK)) { CTC_INTC |= CTC_INTC_ERRIC; - }else{ + } else { CTC_INTC |= flag; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c index b789856..180881c 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_dac.c \brief DAC driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -42,7 +40,7 @@ OF SUCH DAMAGE. #define DH_8BIT_OFFSET ((uint32_t)8U) /*! - \brief deinitialize DAC + \brief deinitialize DAC \param[in] none \param[out] none \retval none @@ -54,97 +52,97 @@ void dac_deinit(void) } /*! - \brief enable DAC + \brief enable DAC \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_enable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL |= DAC_CTL_DEN0; - }else{ + } else { DAC_CTL |= DAC_CTL_DEN1; } -} +} /*! - \brief disable DAC + \brief disable DAC \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL &= ~DAC_CTL_DEN0; - }else{ + } else { DAC_CTL &= ~DAC_CTL_DEN1; } } /*! - \brief enable DAC DMA function + \brief enable DAC DMA function \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_dma_enable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL |= DAC_CTL_DDMAEN0; - }else{ + } else { DAC_CTL |= DAC_CTL_DDMAEN1; } } /*! - \brief disable DAC DMA function + \brief disable DAC DMA function \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_dma_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL &= ~DAC_CTL_DDMAEN0; - }else{ + } else { DAC_CTL &= ~DAC_CTL_DDMAEN1; } } /*! - \brief enable DAC output buffer + \brief enable DAC output buffer \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_output_buffer_enable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL &= ~DAC_CTL_DBOFF0; - }else{ + } else { DAC_CTL &= ~DAC_CTL_DBOFF1; } } /*! - \brief disable DAC output buffer + \brief disable DAC output buffer \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_output_buffer_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL |= DAC_CTL_DBOFF0; - }else{ + } else { DAC_CTL |= DAC_CTL_DBOFF1; } } /*! - \brief get DAC output value + \brief get DAC output value \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval DAC output data @@ -152,10 +150,10 @@ void dac_output_buffer_disable(uint32_t dac_periph) uint16_t dac_output_value_get(uint32_t dac_periph) { uint16_t data = 0U; - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* store the DAC0 output value */ data = (uint16_t)DAC0_DO; - }else{ + } else { /* store the DAC1 output value */ data = (uint16_t)DAC1_DO; } @@ -163,7 +161,7 @@ uint16_t dac_output_value_get(uint32_t dac_periph) } /*! - \brief set the DAC specified data holding register value + \brief set the DAC specified data holding register value \param[in] dac_periph: DACx(x = 0,1) \param[in] dac_align: data alignment only one parameter can be selected which is shown as below: @@ -176,8 +174,8 @@ uint16_t dac_output_value_get(uint32_t dac_periph) */ void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) { - if(DAC0 == dac_periph){ - switch(dac_align){ + if(DAC0 == dac_periph) { + switch(dac_align) { /* data right 12 bit alignment */ case DAC_ALIGN_12B_R: DAC0_R12DH = data; @@ -193,8 +191,8 @@ void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) default: break; } - }else{ - switch(dac_align){ + } else { + switch(dac_align) { /* data right 12 bit alignment */ case DAC_ALIGN_12B_R: DAC1_R12DH = data; @@ -214,37 +212,37 @@ void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) } /*! - \brief enable DAC trigger + \brief enable DAC trigger \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_trigger_enable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL |= DAC_CTL_DTEN0; - }else{ + } else { DAC_CTL |= DAC_CTL_DTEN1; } } /*! - \brief disable DAC trigger + \brief disable DAC trigger \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_trigger_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_CTL &= ~DAC_CTL_DTEN0; - }else{ + } else { DAC_CTL &= ~DAC_CTL_DTEN1; } } /*! - \brief set DAC trigger source + \brief set DAC trigger source \param[in] dac_periph: DACx(x = 0,1) \param[in] triggersource: external triggers of DAC only one parameter can be selected which is shown as below: @@ -259,13 +257,13 @@ void dac_trigger_disable(uint32_t dac_periph) \param[out] none \retval none */ -void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) +void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* configure DAC0 trigger source */ DAC_CTL &= ~DAC_CTL_DTSEL0; DAC_CTL |= triggersource; - }else{ + } else { /* configure DAC1 trigger source */ DAC_CTL &= ~DAC_CTL_DTSEL1; DAC_CTL |= (triggersource << DAC1_REG_OFFSET); @@ -273,36 +271,36 @@ void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource) } /*! - \brief enable DAC software trigger + \brief enable DAC software trigger \param[in] dac_periph: DACx(x = 0,1) \retval none */ void dac_software_trigger_enable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_SWT |= DAC_SWT_SWTR0; - }else{ + } else { DAC_SWT |= DAC_SWT_SWTR1; } } /*! - \brief disable DAC software trigger + \brief disable DAC software trigger \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_software_trigger_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_SWT &= ~DAC_SWT_SWTR0; - }else{ + } else { DAC_SWT &= ~DAC_SWT_SWTR1; } } /*! - \brief configure DAC wave mode + \brief configure DAC wave mode \param[in] dac_periph: DACx(x = 0,1) \param[in] wave_mode: noise wave mode only one parameter can be selected which is shown as below: @@ -314,11 +312,11 @@ void dac_software_trigger_disable(uint32_t dac_periph) */ void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* configure DAC0 wave mode */ DAC_CTL &= ~DAC_CTL_DWM0; DAC_CTL |= wave_mode; - }else{ + } else { /* configure DAC1 wave mode */ DAC_CTL &= ~DAC_CTL_DWM1; DAC_CTL |= (wave_mode << DAC1_REG_OFFSET); @@ -326,7 +324,7 @@ void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode) } /*! - \brief configure DAC wave bit width + \brief configure DAC wave bit width \param[in] dac_periph: DACx(x = 0,1) \param[in] bit_width: noise wave bit width only one parameter can be selected which is shown as below: @@ -347,11 +345,11 @@ void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode) */ void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* configure DAC0 wave bit width */ DAC_CTL &= ~DAC_CTL_DWBW0; DAC_CTL |= bit_width; - }else{ + } else { /* configure DAC1 wave bit width */ DAC_CTL &= ~DAC_CTL_DWBW1; DAC_CTL |= (bit_width << DAC1_REG_OFFSET); @@ -359,7 +357,7 @@ void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width) } /*! - \brief configure DAC LFSR noise mode + \brief configure DAC LFSR noise mode \param[in] dac_periph: DACx(x = 0,1) \param[in] unmask_bits: unmask LFSR bits in DAC LFSR noise mode only one parameter can be selected which is shown as below: @@ -380,11 +378,11 @@ void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width) */ void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* configure DAC0 LFSR noise mode */ DAC_CTL &= ~DAC_CTL_DWBW0; DAC_CTL |= unmask_bits; - }else{ + } else { /* configure DAC1 LFSR noise mode */ DAC_CTL &= ~DAC_CTL_DWBW1; DAC_CTL |= (unmask_bits << DAC1_REG_OFFSET); @@ -392,7 +390,7 @@ void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits) } /*! - \brief configure DAC triangle noise mode + \brief configure DAC triangle noise mode \param[in] dac_periph: DACx(x = 0,1) \param[in] amplitude: triangle amplitude in DAC triangle noise mode only one parameter can be selected which is shown as below: @@ -413,11 +411,11 @@ void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits) */ void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* configure DAC0 triangle noise mode */ DAC_CTL &= ~DAC_CTL_DWBW0; DAC_CTL |= amplitude; - }else{ + } else { /* configure DAC1 triangle noise mode */ DAC_CTL &= ~DAC_CTL_DWBW1; DAC_CTL |= (amplitude << DAC1_REG_OFFSET); @@ -425,7 +423,7 @@ void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude) } /*! - \brief enable DAC concurrent mode + \brief enable DAC concurrent mode \param[in] none \param[out] none \retval none @@ -438,7 +436,7 @@ void dac_concurrent_enable(void) } /*! - \brief disable DAC concurrent mode + \brief disable DAC concurrent mode \param[in] none \param[out] none \retval none @@ -451,7 +449,7 @@ void dac_concurrent_disable(void) } /*! - \brief enable DAC concurrent software trigger function + \brief enable DAC concurrent software trigger function \param[in] none \param[out] none \retval none @@ -460,11 +458,11 @@ void dac_concurrent_software_trigger_enable(void) { uint32_t swt = 0U; swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; - DAC_SWT |= (swt); + DAC_SWT |= (swt); } /*! - \brief disable DAC concurrent software trigger function + \brief disable DAC concurrent software trigger function \param[in] none \param[out] none \retval none @@ -477,7 +475,7 @@ void dac_concurrent_software_trigger_disable(void) } /*! - \brief enable DAC concurrent buffer function + \brief enable DAC concurrent buffer function \param[in] none \param[out] none \retval none @@ -490,7 +488,7 @@ void dac_concurrent_output_buffer_enable(void) } /*! - \brief disable DAC concurrent buffer function + \brief disable DAC concurrent buffer function \param[in] none \param[out] none \retval none @@ -503,7 +501,7 @@ void dac_concurrent_output_buffer_disable(void) } /*! - \brief set DAC concurrent mode data holding register value + \brief set DAC concurrent mode data holding register value \param[in] dac_align: data alignment only one parameter can be selected which is shown as below: \arg DAC_ALIGN_8B_R: data right 8b alignment @@ -517,7 +515,7 @@ void dac_concurrent_output_buffer_disable(void) void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1) { uint32_t data = 0U; - switch(dac_align){ + switch(dac_align) { /* data right 12b alignment */ case DAC_ALIGN_12B_R: data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0; @@ -539,7 +537,7 @@ void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1) } /*! - \brief enable DAC concurrent interrupt funcution + \brief enable DAC concurrent interrupt funcution \param[in] none \param[out] none \retval none @@ -552,7 +550,7 @@ void dac_concurrent_interrupt_enable(void) } /*! - \brief disable DAC concurrent interrupt funcution + \brief disable DAC concurrent interrupt funcution \param[in] none \param[out] none \retval none @@ -565,75 +563,75 @@ void dac_concurrent_interrupt_disable(void) } /*! - \brief enable DAC interrupt(DAC DMA underrun interrupt) + \brief get the specified DAC flag (DAC DMA underrun flag) \param[in] dac_periph: DACx(x = 0,1) \param[out] none - \retval none + \retval FlagStatus: SET or RESET */ -void dac_interrupt_enable(uint32_t dac_periph) +FlagStatus dac_flag_get(uint32_t dac_periph) { - if(DAC0 == dac_periph){ - DAC_CTL |= DAC_CTL_DDUDRIE0; - }else{ - DAC_CTL |= DAC_CTL_DDUDRIE1; + FlagStatus temp_flag = RESET; + if(DAC0 == dac_periph) { + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)) { + temp_flag = SET; + } + } else { + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)) { + temp_flag = SET; + } } + return temp_flag; } /*! - \brief disable DAC interrupt(DAC DMA underrun interrupt) + \brief clear the specified DAC flag (DAC DMA underrun flag) \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ -void dac_interrupt_disable(uint32_t dac_periph) +void dac_flag_clear(uint32_t dac_periph) { - if(DAC0 == dac_periph){ - DAC_CTL &= ~DAC_CTL_DDUDRIE0; - }else{ - DAC_CTL &= ~DAC_CTL_DDUDRIE1; + if(DAC0 == dac_periph) { + DAC_STAT |= DAC_STAT_DDUDR0; + } else { + DAC_STAT |= DAC_STAT_DDUDR1; } } /*! - \brief get the specified DAC flag (DAC DMA underrun flag) + \brief enable DAC interrupt(DAC DMA underrun interrupt) \param[in] dac_periph: DACx(x = 0,1) \param[out] none - \retval FlagStatus: SET or RESET + \retval none */ -FlagStatus dac_flag_get(uint32_t dac_periph) +void dac_interrupt_enable(uint32_t dac_periph) { - FlagStatus temp_flag = RESET; - if(DAC0 == dac_periph){ - /* check the DMA underrun flag */ - if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){ - temp_flag = SET; - } - }else{ - /* check the DMA underrun flag */ - if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){ - temp_flag = SET; - } + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DDUDRIE0; + } else { + DAC_CTL |= DAC_CTL_DDUDRIE1; } - return temp_flag; } /*! - \brief clear the specified DAC flag (DAC DMA underrun flag) + \brief disable DAC interrupt(DAC DMA underrun interrupt) \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ -void dac_flag_clear(uint32_t dac_periph) +void dac_interrupt_disable(uint32_t dac_periph) { - if(DAC0 == dac_periph){ - DAC_STAT |= DAC_STAT_DDUDR0; - }else{ - DAC_STAT |= DAC_STAT_DDUDR1; + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + } else { + DAC_CTL &= ~DAC_CTL_DDUDRIE1; } } /*! - \brief get the specified DAC interrupt flag (DAC DMA underrun interrupt flag) + \brief get the specified DAC interrupt flag (DAC DMA underrun interrupt flag) \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval FlagStatus: SET or RESET @@ -643,18 +641,18 @@ FlagStatus dac_interrupt_flag_get(uint32_t dac_periph) FlagStatus temp_flag = RESET; uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0; ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; - if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)) { temp_flag = SET; } - }else{ + } else { /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1; ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1; - if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){ + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)) { temp_flag = SET; } } @@ -662,16 +660,16 @@ FlagStatus dac_interrupt_flag_get(uint32_t dac_periph) } /*! - \brief clear the specified DAC interrupt flag (DAC DMA underrun interrupt flag) + \brief clear the specified DAC interrupt flag (DAC DMA underrun interrupt flag) \param[in] dac_periph: DACx(x = 0,1) \param[out] none \retval none */ void dac_interrupt_flag_clear(uint32_t dac_periph) { - if(DAC0 == dac_periph){ + if(DAC0 == dac_periph) { DAC_STAT |= DAC_STAT_DDUDR0; - }else{ + } else { DAC_STAT |= DAC_STAT_DDUDR1; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c index 4cbdba5..0fe3a40 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_dbg.c \brief DBG driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -95,29 +93,28 @@ void dbg_low_power_disable(uint32_t dbg_low_power) \brief enable peripheral behavior when the mcu is in debug mode \param[in] dbg_periph: dbg_periph_enum only one parameter can be selected which is shown as below: - \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted - \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted - \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted - \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted - \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted - \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted - \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted - \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted - \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted - \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted - \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted - \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted - \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted - \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted - \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted - \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted - \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted - \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted - \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted - \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted - \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted - \arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted - \arg \param[out] none + \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted + \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted + \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted + \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted + \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted + \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted + \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted + \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted + \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted + \arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted \retval none */ void dbg_periph_enable(dbg_periph_enum dbg_periph) @@ -129,28 +126,28 @@ void dbg_periph_enable(dbg_periph_enum dbg_periph) \brief disable peripheral behavior when the mcu is in debug mode \param[in] dbg_periph: dbg_periph_enum only one parameter can be selected which is shown as below: - \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted - \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted - \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted - \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted - \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted - \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted - \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted - \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted - \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted - \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted - \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted - \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted - \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted - \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted - \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted - \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted - \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted - \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted - \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted - \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted - \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted - \arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted + \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted + \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted + \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted + \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted + \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted + \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted + \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted + \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted + \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted + \arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted \param[out] none \retval none */ @@ -181,18 +178,3 @@ void dbg_trace_pin_disable(void) DBG_CTL0 &= ~DBG_CTL0_TRACE_IOEN; } -/*! - \brief trace pin mode selection - \param[in] trace_mode: - \arg TRACE_MODE_ASYNC: trace pin used for async mode - \arg TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1 - \arg TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2 - \arg TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4 - \param[out] none - \retval none -*/ -void dbg_trace_pin_mode_set(uint32_t trace_mode) -{ - DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE; - DBG_CTL0 |= trace_mode; -} diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c index 45576e2..8548e65 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_dci.c \brief DCI driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -62,7 +60,7 @@ void dci_deinit(void) \param[out] none \retval none */ -void dci_init(dci_parameter_struct* dci_struct) +void dci_init(dci_parameter_struct *dci_struct) { uint32_t reg = 0U; /* disable capture function and DCI */ @@ -79,18 +77,18 @@ void dci_init(dci_parameter_struct* dci_struct) } /*! - \brief enable DCI function + \brief enable DCI function \param[in] none \param[out] none \retval none */ void dci_enable(void) { - DCI_CTL |= DCI_CTL_DCIEN; + DCI_CTL |= DCI_CTL_DCIEN; } /*! - \brief disable DCI function + \brief disable DCI function \param[in] none \param[out] none \retval none @@ -101,7 +99,7 @@ void dci_disable(void) } /*! - \brief enable DCI capture + \brief enable DCI capture \param[in] none \param[out] none \retval none @@ -112,7 +110,7 @@ void dci_capture_enable(void) } /*! - \brief disable DCI capture + \brief disable DCI capture \param[in] none \param[out] none \retval none @@ -123,7 +121,7 @@ void dci_capture_disable(void) } /*! - \brief enable DCI jpeg mode + \brief enable DCI jpeg mode \param[in] none \param[out] none \retval none @@ -134,7 +132,7 @@ void dci_jpeg_enable(void) } /*! - \brief disable DCI jpeg mode + \brief disable DCI jpeg mode \param[in] none \param[out] none \retval none @@ -167,7 +165,7 @@ void dci_crop_window_disable(void) } /*! - \brief configure DCI cropping window + \brief configure DCI cropping window \param[in] start_x: window horizontal start position \param[in] start_y: window vertical start position \param[in] size_width: window horizontal size @@ -177,8 +175,8 @@ void dci_crop_window_disable(void) */ void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height) { - DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y<<16)); - DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height<<16)); + DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y << 16)); + DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16)); } /*! @@ -213,7 +211,7 @@ void dci_embedded_sync_disable(void) */ void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) { - DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24)); + DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24)); } /*! @@ -227,7 +225,7 @@ void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line */ void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) { - DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start<<8) | ((uint32_t)line_end<<16) | ((uint32_t)frame_end<<24)); + DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24)); } /*! @@ -258,18 +256,18 @@ uint32_t dci_data_read(void) FlagStatus dci_flag_get(uint32_t flag) { uint32_t stat = 0U; - - if(flag >> 31){ + + if(flag >> 31) { /* get flag status from DCI_STAT1 register */ stat = DCI_STAT1; - }else{ + } else { /* get flag status from DCI_STAT0 register */ stat = DCI_STAT0; } - - if(flag & stat){ + + if(flag & stat) { return SET; - }else{ + } else { return RESET; } } @@ -279,7 +277,7 @@ FlagStatus dci_flag_get(uint32_t flag) \param[in] interrupt: \arg DCI_INT_EF: end of frame interrupt \arg DCI_INT_OVR: FIFO overrun interrupt - \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt \arg DCI_INT_VSYNC: vsync interrupt \arg DCI_INT_EL: end of line interrupt \param[out] none @@ -295,7 +293,7 @@ void dci_interrupt_enable(uint32_t interrupt) \param[in] interrupt: \arg DCI_INT_EF: end of frame interrupt \arg DCI_INT_OVR: FIFO overrun interrupt - \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt \arg DCI_INT_VSYNC: vsync interrupt \arg DCI_INT_EL: end of line interrupt \param[out] none @@ -311,7 +309,7 @@ void dci_interrupt_disable(uint32_t interrupt) \param[in] int_flag: \arg DCI_INT_EF: end of frame interrupt \arg DCI_INT_OVR: FIFO overrun interrupt - \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt \arg DCI_INT_VSYNC: vsync interrupt \arg DCI_INT_EL: end of line interrupt \param[out] none @@ -327,7 +325,7 @@ void dci_interrupt_flag_clear(uint32_t int_flag) \param[in] int_flag: \arg DCI_INT_FLAG_EF: end of frame interrupt flag \arg DCI_INT_FLAG_OVR: FIFO overrun interrupt flag - \arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag + \arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag \arg DCI_INT_FLAG_VSYNC: vsync interrupt flag \arg DCI_INT_FLAG_EL: end of line interrupt flag \param[out] none @@ -335,9 +333,9 @@ void dci_interrupt_flag_clear(uint32_t int_flag) */ FlagStatus dci_interrupt_flag_get(uint32_t int_flag) { - if(RESET == (DCI_INTF & int_flag)){ + if(RESET == (DCI_INTF & int_flag)) { return RESET; - }else{ + } else { return SET; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c index 1ec4eef..a188938 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c @@ -1,40 +1,36 @@ /*! \file gd32f4xx_dma.c \brief DMA driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_dma.h" /* DMA register bit offset */ @@ -52,19 +48,19 @@ OF SUCH DAMAGE. void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) { /* disable DMA a channel */ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN; + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; /* reset DMA channel registers */ - DMA_CHCTL(dma_periph,channelx) = DMA_CHCTL_RESET_VALUE; - DMA_CHCNT(dma_periph,channelx) = DMA_CHCNT_RESET_VALUE; - DMA_CHPADDR(dma_periph,channelx) = DMA_CHPADDR_RESET_VALUE; - DMA_CHM0ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE; - DMA_CHM1ADDR(dma_periph,channelx) = DMA_CHMADDR_RESET_VALUE; - DMA_CHFCTL(dma_periph,channelx) = DMA_CHFCTL_RESET_VALUE; - if(channelx < DMA_CH4){ - DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); - }else{ + DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHM0ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHM1ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHFCTL(dma_periph, channelx) = DMA_CHFCTL_RESET_VALUE; + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); + } else { channelx -= (dma_channel_enum)4; - DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx); + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); } } @@ -74,7 +70,7 @@ void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) \param[out] none \retval none */ -void dma_single_data_para_struct_init(dma_single_data_parameter_struct* init_struct) +void dma_single_data_para_struct_init(dma_single_data_parameter_struct *init_struct) { /* set the DMA struct with the default values */ init_struct->periph_addr = 0U; @@ -94,7 +90,7 @@ void dma_single_data_para_struct_init(dma_single_data_parameter_struct* init_str \param[out] none \retval none */ -void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct* init_struct) +void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct *init_struct) { /* set the DMA struct with the default values */ init_struct->periph_addr = 0U; @@ -123,56 +119,56 @@ void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct* init_struc memory0_addr: memory base address memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE periph_memory_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT - circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE + circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY number: the number of remaining data to be transferred by the DMA - priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH \param[out] none \retval none */ -void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct* init_struct) +void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct *init_struct) { uint32_t ctl; - + /* select single data mode */ - DMA_CHFCTL(dma_periph,channelx) &= ~DMA_CHXFCTL_MDMEN; - + DMA_CHFCTL(dma_periph, channelx) &= ~DMA_CHXFCTL_MDMEN; + /* configure peripheral base address */ - DMA_CHPADDR(dma_periph,channelx) = init_struct->periph_addr; - + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + /* configure memory base address */ - DMA_CHM0ADDR(dma_periph,channelx) = init_struct->memory0_addr; - + DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr; + /* configure the number of remaining data to be transferred */ - DMA_CHCNT(dma_periph,channelx) = init_struct->number; - + DMA_CHCNT(dma_periph, channelx) = init_struct->number; + /* configure peripheral and memory transfer width,channel priotity,transfer mode */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM); ctl |= (init_struct->periph_memory_width | (init_struct->periph_memory_width << 2) | init_struct->priority | init_struct->direction); - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; /* configure peripheral increasing mode */ - if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; - }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc){ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; } /* configure memory increasing mode */ - if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; } /* configure DMA circular mode */ - if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; - }else{ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; + if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; } } @@ -185,7 +181,7 @@ void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, d \param[in] dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode periph_addr: peripheral base address periph_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT - periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX memory0_addr: memory0 base address memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE @@ -195,53 +191,54 @@ void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, d circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY number: the number of remaining data to be transferred by the DMA - priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH \param[out] none \retval none */ -void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct* init_struct) +void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct *init_struct) { uint32_t ctl; - + /* select multi data mode and configure FIFO critical value */ - DMA_CHFCTL(dma_periph,channelx) |= (DMA_CHXFCTL_MDMEN | init_struct->critical_value); - + DMA_CHFCTL(dma_periph, channelx) |= (DMA_CHXFCTL_MDMEN | init_struct->critical_value); + /* configure peripheral base address */ - DMA_CHPADDR(dma_periph,channelx) = init_struct->periph_addr; - + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + /* configure memory base address */ - DMA_CHM0ADDR(dma_periph,channelx) = init_struct->memory0_addr; - + DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr; + /* configure the number of remaining data to be transferred */ - DMA_CHCNT(dma_periph,channelx) = init_struct->number; - + DMA_CHCNT(dma_periph, channelx) = init_struct->number; + /* configure peripheral and memory transfer width,channel priotity,transfer mode,peripheral and memory burst transfer width */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM | DMA_CHXCTL_PBURST | DMA_CHXCTL_MBURST); - ctl |= (init_struct->periph_width | (init_struct->memory_width ) | init_struct->priority | init_struct->direction | init_struct->memory_burst_width | init_struct->periph_burst_width); - DMA_CHCTL(dma_periph,channelx) = ctl; + ctl |= (init_struct->periph_width | (init_struct->memory_width) | init_struct->priority | init_struct->direction | init_struct->memory_burst_width | + init_struct->periph_burst_width); + DMA_CHCTL(dma_periph, channelx) = ctl; /* configure peripheral increasing mode */ - if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; - }else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc){ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; } /* configure memory increasing mode */ - if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; } /* configure DMA circular mode */ - if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; - }else{ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; + if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; } } @@ -257,14 +254,14 @@ void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dm */ void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) { - DMA_CHPADDR(dma_periph,channelx) = address; + DMA_CHPADDR(dma_periph, channelx) = address; } /*! \brief set DMA Memory0 base address \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel to set Memory base address + \param[in] channelx: specify which DMA channel to set Memory base address \arg DMA_CHx(x=0..7) \param[in] memory_flag: DMA_MEMORY_x(x=0,1) \param[in] address: Memory base address @@ -273,10 +270,10 @@ void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, u */ void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t memory_flag, uint32_t address) { - if(memory_flag){ - DMA_CHM1ADDR(dma_periph,channelx) = address; - }else{ - DMA_CHM0ADDR(dma_periph,channelx) = address; + if(memory_flag) { + DMA_CHM1ADDR(dma_periph, channelx) = address; + } else { + DMA_CHM0ADDR(dma_periph, channelx) = address; } } @@ -292,21 +289,21 @@ void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, u */ void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number) { - DMA_CHCNT(dma_periph,channelx) = number; + DMA_CHCNT(dma_periph, channelx) = number; } /*! \brief get the number of remaining data to be transferred by the DMA \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel to set number + \param[in] channelx: specify which DMA channel to set number \arg DMA_CHx(x=0..7) \param[out] none - \retval uint32_t: the number of remaining data to be transferred by the DMA + \retval uint32_t: the number of remaining data to be transferred by the DMA */ uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx) { - return (uint32_t)DMA_CHCNT(dma_periph,channelx); + return (uint32_t)DMA_CHCNT(dma_periph, channelx); } /*! @@ -322,17 +319,17 @@ uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx) \arg DMA_PRIORITY_HIGH: high priority \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority \param[out] none - \retval none + \retval none */ void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority) { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_PRIO; ctl |= priority; - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! @@ -349,15 +346,15 @@ void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_ \param[out] none \retval none */ -void dma_memory_burst_beats_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t mbeat) +void dma_memory_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mbeat) { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_MBURST; ctl |= mbeat; - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! @@ -375,15 +372,15 @@ void dma_memory_burst_beats_config (uint32_t dma_periph, dma_channel_enum channe \param[out] none \retval none */ -void dma_periph_burst_beats_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t pbeat) +void dma_periph_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pbeat) { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_PBURST; ctl |= pbeat; - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! @@ -404,18 +401,18 @@ void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uin { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_MWIDTH; ctl |= msize; - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! - \brief configure transfer data size of peripheral + \brief configure transfer data size of peripheral \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] msize: transfer data size of peripheral only one parameter can be selected which is shown as below: @@ -425,22 +422,22 @@ void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uin \param[out] none \retval none */ -void dma_periph_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t psize) +void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t psize) { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_PWIDTH; ctl |= psize; - DMA_CHCTL(dma_periph,channelx) = ctl; + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! \brief configure memory address generation generation_algorithm \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] generation_algorithm: the address generation algorithm only one parameter can be selected which is shown as below: @@ -451,10 +448,10 @@ void dma_periph_width_config (uint32_t dma_periph, dma_channel_enum channelx, ui */ void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm) { - if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MNAGA; + if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; } } @@ -462,7 +459,7 @@ void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum \brief configure peripheral address generation_algorithm \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] generation_algorithm: the address generation algorithm only one parameter can be selected which is shown as below: @@ -474,13 +471,13 @@ void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum */ void dma_peripheral_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm) { - if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm){ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; - }else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm){ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_PNAGA; - }else{ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PNAGA; - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_PAIF; + if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; } } @@ -488,63 +485,63 @@ void dma_peripheral_address_generation_config(uint32_t dma_periph, dma_channel_e \brief enable DMA circulation mode \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval none + \retval none */ void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx) { - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CMEN; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; } /*! \brief disable DMA circulation mode \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval none + \retval none */ void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx) { - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CMEN; + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; } /*! \brief enable DMA channel \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval none + \retval none */ void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx) { - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_CHEN; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN; } /*! \brief disable DMA channel \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval none + \retval none */ void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx) { - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_CHEN; + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; } /*! \brief configure the direction of data transfer on the channel \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] direction: specify the direction of data transfer only one parameter can be selected which is shown as below: @@ -558,34 +555,34 @@ void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channel { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_TM; ctl |= direction; - - DMA_CHCTL(dma_periph,channelx) = ctl; + + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! \brief DMA switch buffer mode config \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] memory1_addr: memory1 base address \param[in] memory_select: DMA_MEMORY_0 or DMA_MEMORY_1 \param[out] none - \retval none + \retval none */ void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t memory1_addr, uint32_t memory_select) { /* configure memory1 base address */ - DMA_CHM1ADDR(dma_periph,channelx) = memory1_addr; + DMA_CHM1ADDR(dma_periph, channelx) = memory1_addr; - if(DMA_MEMORY_0 == memory_select){ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_MBS; - }else{ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_MBS; + if(DMA_MEMORY_0 == memory_select) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MBS; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MBS; } } @@ -593,16 +590,16 @@ void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channel \brief DMA using memory get \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval the using memory + \retval the using memory */ uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx) { - if((DMA_CHCTL(dma_periph,channelx)) & DMA_CHXCTL_MBS){ + if((DMA_CHCTL(dma_periph, channelx)) & DMA_CHXCTL_MBS) { return DMA_MEMORY_1; - }else{ + } else { return DMA_MEMORY_0; } } @@ -611,32 +608,32 @@ uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx) \brief DMA channel peripheral select \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] sub_periph: specify DMA channel peripheral \arg DMA_SUBPERIx(x=0..7) \param[out] none - \retval none + \retval none */ void dma_channel_subperipheral_select(uint32_t dma_periph, dma_channel_enum channelx, dma_subperipheral_enum sub_periph) { uint32_t ctl; /* acquire DMA_CHxCTL register */ - ctl = DMA_CHCTL(dma_periph,channelx); + ctl = DMA_CHCTL(dma_periph, channelx); /* assign regiser */ ctl &= ~DMA_CHXCTL_PERIEN; ctl |= ((uint32_t)sub_periph << CHXCTL_PERIEN_OFFSET); - - DMA_CHCTL(dma_periph,channelx) = ctl; + + DMA_CHCTL(dma_periph, channelx) = ctl; } /*! \brief DMA flow controller configure \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) - \param[in] controller: specify DMA flow controler + \param[in] controller: specify DMA flow controler only one parameter can be selected which is shown as below: \arg DMA_FLOW_CONTROLLER_DMA: DMA is the flow controller \arg DMA_FLOW_CONTROLLER_PERI: peripheral is the flow controller @@ -645,10 +642,10 @@ void dma_channel_subperipheral_select(uint32_t dma_periph, dma_channel_enum chan */ void dma_flow_controller_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t controller) { - if(DMA_FLOW_CONTROLLER_DMA == controller){ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_TFCS; - }else{ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_TFCS; + if(DMA_FLOW_CONTROLLER_DMA == controller) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_TFCS; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_TFCS; } } @@ -656,20 +653,20 @@ void dma_flow_controller_config(uint32_t dma_periph, dma_channel_enum channelx, \brief DMA switch buffer mode enable \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[in] newvalue: ENABLE or DISABLE \param[out] none - \retval none + \retval none */ void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx, ControlStatus newvalue) { - if(ENABLE == newvalue){ + if(ENABLE == newvalue) { /* switch buffer mode enable */ - DMA_CHCTL(dma_periph,channelx) |= DMA_CHXCTL_SBMEN; - }else{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_SBMEN; + } else { /* switch buffer mode disable */ - DMA_CHCTL(dma_periph,channelx) &= ~DMA_CHXCTL_SBMEN; + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_SBMEN; } } @@ -677,18 +674,18 @@ void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channel \brief DMA FIFO status get \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel + \param[in] channelx: specify which DMA channel \arg DMA_CHx(x=0..7) \param[out] none - \retval the using memory + \retval the using memory */ uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx) { - return (DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FCNT); + return (DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FCNT); } /*! - \brief get DMA flag is set or not + \brief get DMA flag is set or not \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) \param[in] channelx: specify which DMA channel to get flag @@ -705,17 +702,17 @@ uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx) */ FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { - if(channelx < DMA_CH4){ - if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag,channelx)){ + if(channelx < DMA_CH4) { + if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx)) { return SET; - }else{ + } else { return RESET; } - }else{ + } else { channelx -= (dma_channel_enum)4; - if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag,channelx)){ + if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channelx)) { return SET; - }else{ + } else { return RESET; } } @@ -739,16 +736,66 @@ FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t */ void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) { - if(channelx < DMA_CH4){ - DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag,channelx); - }else{ + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag, channelx); + } else { channelx -= (dma_channel_enum)4; - DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag,channelx); + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag, channelx); + } +} + +/*! + \brief enable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to enbale + only one parameters can be selected which are shown as below: + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source) { + DMA_CHCTL(dma_periph, channelx) |= source; + } else { + DMA_CHFCTL(dma_periph, channelx) |= source; } } /*! - \brief get DMA interrupt flag is set or not + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to disbale + only one parameters can be selected which are shown as below: + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source) { + DMA_CHCTL(dma_periph, channelx) &= ~source; + } else { + DMA_CHFCTL(dma_periph, channelx) &= ~source; + } +} + +/*! + \brief get DMA interrupt flag is set or not \param[in] dma_periph: DMAx(x=0,1) \arg DMAx(x=0,1) \param[in] channelx: specify which DMA channel to get interrupt flag @@ -765,64 +812,64 @@ void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t fla */ FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt) { - uint32_t interrupt_enable = 0U,interrupt_flag = 0U; + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; dma_channel_enum channel_flag_offset = channelx; - if(channelx < DMA_CH4){ - switch(interrupt){ + if(channelx < DMA_CH4) { + switch(interrupt) { case DMA_INTF_FEEIF: - interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); - interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE; + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; break; case DMA_INTF_SDEIF: - interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE; + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; break; case DMA_INTF_TAEIF: - interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE; + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; break; case DMA_INTF_HTFIF: - interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE; + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; break; case DMA_INTF_FTFIF: - interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt,channelx)); - interrupt_enable = (DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE); + interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx)); + interrupt_enable = (DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE); break; default: break; } - }else{ + } else { channel_flag_offset -= (dma_channel_enum)4; - switch(interrupt){ + switch(interrupt) { case DMA_INTF_FEEIF: - interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); - interrupt_enable = DMA_CHFCTL(dma_periph,channelx) & DMA_CHXFCTL_FEEIE; + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; break; case DMA_INTF_SDEIF: - interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_SDEIE; + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; break; case DMA_INTF_TAEIF: - interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_TAEIE; + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; break; case DMA_INTF_HTFIF: - interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_HTFIE; + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; break; case DMA_INTF_FTFIF: - interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt,channel_flag_offset); - interrupt_enable = DMA_CHCTL(dma_periph,channelx) & DMA_CHXCTL_FTFIE; + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; break; default: break; } } - - if(interrupt_flag && interrupt_enable){ + + if(interrupt_flag && interrupt_enable) { return SET; - }else{ + } else { return RESET; } } @@ -845,61 +892,10 @@ FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx */ void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt) { - if(channelx < DMA_CH4){ - DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx); - }else{ + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx); + } else { channelx -= (dma_channel_enum)4; - DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt,channelx); + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx); } } - -/*! - \brief enable DMA interrupt - \param[in] dma_periph: DMAx(x=0,1) - \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel - \arg DMA_CHx(x=0..7) - \param[in] source: specify which interrupt to enbale - one or more parameters can be selected which are shown as below: - \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable - \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable - \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable - \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable - \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable - \param[out] none - \retval none -*/ -void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) -{ - if(DMA_CHXFCTL_FEEIE != source){ - DMA_CHCTL(dma_periph,channelx) |= source; - }else{ - DMA_CHFCTL(dma_periph,channelx) |= source; - } -} - -/*! - \brief disable DMA interrupt - \param[in] dma_periph: DMAx(x=0,1) - \arg DMAx(x=0,1) - \param[in] channelx: specify which DMA channel - \arg DMA_CHx(x=0..7) - \param[in] source: specify which interrupt to disbale - one or more parameters can be selected which are shown as below: - \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable - \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable - \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable - \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable - \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable - \param[out] none - \retval none -*/ -void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) -{ - if(DMA_CHXFCTL_FEEIE != source){ - DMA_CHCTL(dma_periph,channelx) &= ~source; - }else{ - DMA_CHFCTL(dma_periph,channelx) &= ~source; - } -} - diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c index 3432058..4065944 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c @@ -2,48 +2,45 @@ \file gd32f4xx_enet.c \brief ENET driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. - - Redistribution and use in source and binary forms, with or without modification, + Copyright (c) 2023, GigaDevice Semiconductor Inc. + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_enet.h" #if defined (__CC_ARM) /*!< ARM compiler */ -__align(4) +__align(4) enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ -__align(4) +__align(4) enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ -__align(4) +__align(4) uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ -__align(4) +__align(4) uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ #elif defined ( __ICCARM__ ) /*!< IAR compiler */ @@ -57,10 +54,10 @@ uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive bu uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ #elif defined (__GNUC__) /* GNU Compiler */ -enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM] __attribute__ ((aligned (4))); /*!< ENET RxDMA descriptor */ -enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM] __attribute__ ((aligned (4))); /*!< ENET TxDMA descriptor */ -uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE] __attribute__ ((aligned (4))); /*!< ENET receive buffer */ -uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE] __attribute__ ((aligned (4))); /*!< ENET transmit buffer */ +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM] __attribute__((aligned(4))); /*!< ENET RxDMA descriptor */ +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM] __attribute__((aligned(4))); /*!< ENET TxDMA descriptor */ +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE] __attribute__((aligned(4))); /*!< ENET receive buffer */ +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE] __attribute__((aligned(4))); /*!< ENET transmit buffer */ #endif /* __CC_ARM */ @@ -73,25 +70,26 @@ enet_descriptors_struct *dma_current_ptp_txdesc = NULL; enet_descriptors_struct *dma_current_ptp_rxdesc = NULL; /* init structure parameters for ENET initialization */ -static enet_initpara_struct enet_initpara ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +static enet_initpara_struct enet_initpara = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static uint32_t enet_unknow_err = 0U; /* array of register offset for debug information get */ static const uint16_t enet_reg_tab[] = { -0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0028, 0x002C, 0x0034, -0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x1080, - -0x0100, 0x0104, 0x0108, 0x010C, 0x0110, 0x014C, 0x0150, 0x0168, 0x0194, 0x0198, 0x01C4, - -0x0700, 0x0704,0x0708, 0x070C, 0x0710, 0x0714, 0x0718, 0x071C, 0x0720, 0x0728, 0x072C, - -0x1000, 0x1004, 0x1008, 0x100C, 0x1010, 0x1014, 0x1018, 0x101C, 0x1020, 0x1024, 0x1048, -0x104C, 0x1050, 0x1054}; + 0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0028, 0x002C, 0x0034, + 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x1080, + + 0x0100, 0x0104, 0x0108, 0x010C, 0x0110, 0x014C, 0x0150, 0x0168, 0x0194, 0x0198, 0x01C4, + + 0x0700, 0x0704, 0x0708, 0x070C, 0x0710, 0x0714, 0x0718, 0x071C, 0x0720, 0x0728, 0x072C, + + 0x1000, 0x1004, 0x1008, 0x100C, 0x1010, 0x1014, 0x1018, 0x101C, 0x1020, 0x1024, 0x1048, + 0x104C, 0x1050, 0x1054 +}; /* initialize ENET peripheral with generally concerned parameters, call it by enet_init() */ static void enet_default_init(void); #ifdef USE_DELAY /* user can provide more timing precise _ENET_DELAY_ function */ -#define _ENET_DELAY_ delay_ms +#define _ENET_DELAY_ delay_ms #else /* insert a delay time */ static void enet_delay(uint32_t ncount); @@ -115,7 +113,7 @@ void enet_deinit(void) /*! \brief configure the parameters which are usually less cared for initialization - note -- this function must be called before enet_init(), otherwise + note -- this function must be called before enet_init(), otherwise configuration will be no effect \param[in] option: different function option, which is related to several parameters, refer to enet_option_enum only one parameter can be selected which is shown as below @@ -124,7 +122,7 @@ void enet_deinit(void) \arg DMA_MAXBURST_OPTION: choose to configure the DMA max burst related parameters \arg DMA_ARBITRATION_OPTION: choose to configure the DMA arbitration related parameters \arg STORE_OPTION: choose to configure the store forward mode related parameters - \arg DMA_OPTION: choose to configure the DMA descriptor related parameters + \arg DMA_OPTION: choose to configure the DMA descriptor related parameters \arg VLAN_OPTION: choose to configure vlan related parameters \arg FLOWCTL_OPTION: choose to configure flow control related parameters \arg HASHH_OPTION: choose to configure hash high @@ -133,7 +131,7 @@ void enet_deinit(void) \arg HALFDUPLEX_OPTION: choose to configure halfduplex mode related parameters \arg TIMER_OPTION: choose to configure time counter related parameters \arg INTERFRAMEGAP_OPTION: choose to configure the inter frame gap related parameters - \param[in] para: the related parameters according to the option + \param[in] para: the related parameters according to the option all the related parameters should be configured which are shown as below FORWARD_OPTION related parameters: - ENET_AUTO_PADCRC_DROP_ENABLE/ ENET_AUTO_PADCRC_DROP_DISABLE ; @@ -179,7 +177,7 @@ void enet_deinit(void) FLOWCTL_OPTION related parameters: - MAC_FCTL_PTM(regval) ; - ENET_ZERO_QUANTA_PAUSE_ENABLE/ ENET_ZERO_QUANTA_PAUSE_DISABLE ; - - ENET_PAUSETIME_MINUS4/ ENET_PAUSETIME_MINUS28/ + - ENET_PAUSETIME_MINUS4/ ENET_PAUSETIME_MINUS28/ ENET_PAUSETIME_MINUS144/ENET_PAUSETIME_MINUS256 ; - ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT/ ENET_UNIQUE_PAUSEDETECT ; - ENET_RX_FLOWCONTROL_ENABLE/ ENET_RX_FLOWCONTROL_DISABLE ; @@ -226,7 +224,7 @@ void enet_deinit(void) */ void enet_initpara_config(enet_option_enum option, uint32_t para) { - switch(option){ + switch(option) { case FORWARD_OPTION: /* choose to configure forward_frame, and save the configuration parameters */ enet_initpara.option_enable |= (uint32_t)FORWARD_OPTION; @@ -255,11 +253,11 @@ void enet_initpara_config(enet_option_enum option, uint32_t para) case DMA_OPTION: /* choose to configure dma_function, and save the configuration parameters */ enet_initpara.option_enable |= (uint32_t)DMA_OPTION; - + #ifndef SELECT_DESCRIPTORS_ENHANCED_MODE para &= ~ENET_ENHANCED_DESCRIPTOR; -#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ - +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + enet_initpara.dma_function = para; break; case VLAN_OPTION: @@ -295,7 +293,7 @@ void enet_initpara_config(enet_option_enum option, uint32_t para) case TIMER_OPTION: /* choose to configure timer_config, and save the configuration parameters */ enet_initpara.option_enable |= (uint32_t)TIMER_OPTION; - enet_initpara.timer_config = para; + enet_initpara.timer_config = para; break; case INTERFRAMEGAP_OPTION: /* choose to configure interframegap, and save the configuration parameters */ @@ -303,14 +301,14 @@ void enet_initpara_config(enet_option_enum option, uint32_t para) enet_initpara.interframegap = para; break; default: - break; - } -} + break; + } +} /*! - \brief initialize ENET peripheral with generally concerned parameters and the less cared + \brief initialize ENET peripheral with generally concerned parameters and the less cared parameters - \param[in] mediamode: PHY mode and mac loopback configurations, refer to enet_mediamode_enum + \param[in] mediamode: PHY mode and mac loopback configurations, refer to enet_mediamode_enum only one parameter can be selected which is shown as below \arg ENET_AUTO_NEGOTIATION: PHY auto negotiation \arg ENET_100M_FULLDUPLEX: 100Mbit/s, full-duplex @@ -318,13 +316,13 @@ void enet_initpara_config(enet_option_enum option, uint32_t para) \arg ENET_10M_FULLDUPLEX: 10Mbit/s, full-duplex \arg ENET_10M_HALFDUPLEX: 10Mbit/s, half-duplex \arg ENET_LOOPBACKMODE: MAC in loopback mode at the MII - \param[in] checksum: IP frame checksum offload function, refer to enet_mediamode_enum + \param[in] checksum: IP frame checksum offload function, refer to enet_mediamode_enum only one parameter can be selected which is shown as below \arg ENET_NO_AUTOCHECKSUM: disable IP frame checksum function \arg ENET_AUTOCHECKSUM_DROP_FAILFRAMES: enable IP frame checksum function \arg ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES: enable IP frame checksum function, and the received frame with only payload error but no other errors will not be dropped - \param[in] recept: frame filter function, refer to enet_frmrecept_enum + \param[in] recept: frame filter function, refer to enet_frmrecept_enum only one parameter can be selected which is shown as below \arg ENET_PROMISCUOUS_MODE: promiscuous mode enabled \arg ENET_RECEIVEALL: all received frame are forwarded to application @@ -335,193 +333,193 @@ void enet_initpara_config(enet_option_enum option, uint32_t para) */ ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept) { - uint32_t reg_value=0U, reg_temp = 0U, temp = 0U; + uint32_t reg_value = 0U, reg_temp = 0U, temp = 0U; uint32_t media_temp = 0U; uint32_t timeout = 0U; uint16_t phy_value = 0U; - ErrStatus phy_state= ERROR, enet_state = ERROR; + ErrStatus phy_state = ERROR, enet_state = ERROR; /* PHY interface configuration, configure SMI clock and reset PHY chip */ -// if(ERROR == enet_phy_config()){ -// _ENET_DELAY_(PHY_RESETDELAY); -// if(ERROR == enet_phy_config()){ -// return enet_state; -// } -// } +/** AvV **/ +// if(ERROR == enet_phy_config()) { +// _ENET_DELAY_(PHY_RESETDELAY); +// if(ERROR == enet_phy_config()) { +// return enet_state; +// } +// } +/** AvV **/ /* initialize ENET peripheral with generally concerned parameters */ enet_default_init(); /* 1st, configure mediamode */ media_temp = (uint32_t)mediamode; /* if is PHY auto negotiation */ - if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp){ + if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp) { /* wait for PHY_LINKED_STATUS bit be set */ - do{ + do { enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); - phy_value &= PHY_LINKED_STATUS; + phy_value &= PHY_LINKED_STATUS; timeout++; - }while((RESET == phy_value) && (timeout < PHY_READ_TO)); + } while((RESET == phy_value) && (timeout < PHY_READ_TO)); /* return ERROR due to timeout */ - if(PHY_READ_TO == timeout){ + if(PHY_READ_TO == timeout) { return enet_state; } - /* reset timeout counter */ timeout = 0U; /* enable auto-negotiation */ phy_value = PHY_AUTONEGOTIATION; phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); - if(!phy_state){ + if(!phy_state) { /* return ERROR due to write timeout */ return enet_state; } /* wait for the PHY_AUTONEGO_COMPLETE bit be set */ - do{ + do { enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); phy_value &= PHY_AUTONEGO_COMPLETE; timeout++; - }while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO)); + } while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO)); /* return ERROR due to timeout */ - if(PHY_READ_TO == timeout){ + if(PHY_READ_TO == timeout) { return enet_state; } - /* reset timeout counter */ timeout = 0U; /* read the result of the auto-negotiation */ - enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value); + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value); /* configure the duplex mode of MAC following the auto-negotiation result */ - if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)){ + if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)) { media_temp = ENET_MODE_FULLDUPLEX; - }else{ + } else { media_temp = ENET_MODE_HALFDUPLEX; } - + /* configure the communication speed of MAC following the auto-negotiation result */ #if(PHY_TYPE == RTL8201F) /** AvV **/ if ((uint16_t) RESET == (phy_value & PHY_SPEED_STATUS)) { #else if ((uint16_t) RESET != (phy_value & PHY_SPEED_STATUS)) { #endif - media_temp |= ENET_SPEEDMODE_10M; - } else { - media_temp |= ENET_SPEEDMODE_100M; - } - }else{ -// phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3); -// phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1); -// phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); -// if(!phy_state){ -// /* return ERROR due to write timeout */ -// return enet_state; -// } -// /* PHY configuration need some time */ -// _ENET_DELAY_(PHY_CONFIGDELAY); + media_temp |= ENET_SPEEDMODE_10M; + } else { + media_temp |= ENET_SPEEDMODE_100M; + } + } else { +// phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3); +// phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1); +// phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); +// if(!phy_state) { +// /* return ERROR due to write timeout */ +// return enet_state; +// } +// /* PHY configuration need some time */ +// _ENET_DELAY_(PHY_CONFIGDELAY); } /* after configuring the PHY, use mediamode to configure registers */ reg_value = ENET_MAC_CFG; /* configure ENET_MAC_CFG register */ - reg_value &= (~(ENET_MAC_CFG_SPD |ENET_MAC_CFG_DPM |ENET_MAC_CFG_LBM)); + reg_value &= (~(ENET_MAC_CFG_SPD | ENET_MAC_CFG_DPM | ENET_MAC_CFG_LBM)); reg_value |= media_temp; ENET_MAC_CFG = reg_value; - - + + /* 2st, configure checksum */ - if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)){ + if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)) { ENET_MAC_CFG |= ENET_CHECKSUMOFFLOAD_ENABLE; - + reg_value = ENET_DMA_CTL; /* configure ENET_DMA_CTL register */ reg_value &= ~ENET_DMA_CTL_DTCERFD; reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD); ENET_DMA_CTL = reg_value; } - + /* 3rd, configure recept */ ENET_MAC_FRMF |= (uint32_t)recept; /* 4th, configure different function options */ /* configure forward_frame related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)) { reg_temp = enet_initpara.forward_frame; reg_value = ENET_MAC_CFG; temp = reg_temp; /* configure ENET_MAC_CFG register */ - reg_value &= (~(ENET_MAC_CFG_TFCD |ENET_MAC_CFG_APCD)); + reg_value &= (~(ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD)); temp &= (ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD); reg_value |= temp; ENET_MAC_CFG = reg_value; - + reg_value = ENET_DMA_CTL; temp = reg_temp; /* configure ENET_DMA_CTL register */ - reg_value &= (~(ENET_DMA_CTL_FERF |ENET_DMA_CTL_FUF)); + reg_value &= (~(ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF)); temp &= ((ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF) << 2); reg_value |= (temp >> 2); ENET_DMA_CTL = reg_value; } /* configure dmabus_mode related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)) { temp = enet_initpara.dmabus_mode; - + reg_value = ENET_DMA_BCTL; /* configure ENET_DMA_BCTL register */ reg_value &= ~(ENET_DMA_BCTL_AA | ENET_DMA_BCTL_FB \ - |ENET_DMA_BCTL_FPBL | ENET_DMA_BCTL_MB); + | ENET_DMA_BCTL_FPBL | ENET_DMA_BCTL_MB); reg_value |= temp; ENET_DMA_BCTL = reg_value; } /* configure dma_maxburst related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)) { temp = enet_initpara.dma_maxburst; - + reg_value = ENET_DMA_BCTL; /* configure ENET_DMA_BCTL register */ - reg_value &= ~(ENET_DMA_BCTL_RXDP| ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP); + reg_value &= ~(ENET_DMA_BCTL_RXDP | ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP); reg_value |= temp; ENET_DMA_BCTL = reg_value; } /* configure dma_arbitration related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)) { temp = enet_initpara.dma_arbitration; - + reg_value = ENET_DMA_BCTL; /* configure ENET_DMA_BCTL register */ reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB); reg_value |= temp; ENET_DMA_BCTL = reg_value; } - + /* configure store_forward_mode related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)) { temp = enet_initpara.store_forward_mode; - + reg_value = ENET_DMA_CTL; /* configure ENET_DMA_CTL register */ - reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD| ENET_DMA_CTL_RTHC| ENET_DMA_CTL_TTHC); + reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD | ENET_DMA_CTL_RTHC | ENET_DMA_CTL_TTHC); reg_value |= temp; ENET_DMA_CTL = reg_value; } /* configure dma_function related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)) { reg_temp = enet_initpara.dma_function; - + reg_value = ENET_DMA_CTL; temp = reg_temp; /* configure ENET_DMA_CTL register */ - reg_value &= (~(ENET_DMA_CTL_DAFRF |ENET_DMA_CTL_OSF)); + reg_value &= (~(ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF)); temp &= (ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF); reg_value |= temp; ENET_DMA_CTL = reg_value; - + reg_value = ENET_DMA_BCTL; temp = reg_temp; /* configure ENET_DMA_BCTL register */ @@ -532,9 +530,9 @@ ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum } /* configure vlan_config related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)) { reg_temp = enet_initpara.vlan_config; - + reg_value = ENET_MAC_VLT; /* configure ENET_MAC_VLT register */ reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC); @@ -543,84 +541,84 @@ ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum } /* configure flow_control related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)) { reg_temp = enet_initpara.flow_control; reg_value = ENET_MAC_FCTL; temp = reg_temp; /* configure ENET_MAC_FCTL register */ - reg_value &= ~(ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \ - | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN); - temp &= (ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \ - | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN); + reg_value &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_DZQP | ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT | ENET_MAC_FCTL_RFCEN | ENET_MAC_FCTL_TFCEN); + temp &= (ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_DZQP | ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT | ENET_MAC_FCTL_RFCEN | ENET_MAC_FCTL_TFCEN); reg_value |= temp; ENET_MAC_FCTL = reg_value; reg_value = ENET_MAC_FCTH; temp = reg_temp; /* configure ENET_MAC_FCTH register */ - reg_value &= ~(ENET_MAC_FCTH_RFA |ENET_MAC_FCTH_RFD); - temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD ) << 8); + reg_value &= ~(ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD); + temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD) << 8); reg_value |= (temp >> 8); ENET_MAC_FCTH = reg_value; } /* configure hashtable_high related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)) { ENET_MAC_HLH = enet_initpara.hashtable_high; - } + } /* configure hashtable_low related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)) { ENET_MAC_HLL = enet_initpara.hashtable_low; - } + } /* configure framesfilter_mode related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)) { reg_temp = enet_initpara.framesfilter_mode; - + reg_value = ENET_MAC_FRMF; /* configure ENET_MAC_FRMF register */ reg_value &= ~(ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT | ENET_MAC_FRMF_DAIFLT \ - | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \ - | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM); + | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \ + | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM); reg_value |= reg_temp; ENET_MAC_FRMF = reg_value; - } + } /* configure halfduplex_param related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)) { reg_temp = enet_initpara.halfduplex_param; - + reg_value = ENET_MAC_CFG; /* configure ENET_MAC_CFG register */ reg_value &= ~(ENET_MAC_CFG_CSD | ENET_MAC_CFG_ROD | ENET_MAC_CFG_RTD \ - | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC); + | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC); reg_value |= reg_temp; ENET_MAC_CFG = reg_value; - } + } /* configure timer_config related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)) { reg_temp = enet_initpara.timer_config; - + reg_value = ENET_MAC_CFG; /* configure ENET_MAC_CFG register */ reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD); reg_value |= reg_temp; ENET_MAC_CFG = reg_value; - } - + } + /* configure interframegap related registers */ - if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)){ + if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)) { reg_temp = enet_initpara.interframegap; - + reg_value = ENET_MAC_CFG; /* configure ENET_MAC_CFG register */ reg_value &= ~ENET_MAC_CFG_IGBS; reg_value |= reg_temp; ENET_MAC_CFG = reg_value; - } + } enet_state = SUCCESS; return enet_state; @@ -637,21 +635,21 @@ ErrStatus enet_software_reset(void) uint32_t timeout = 0U; ErrStatus enet_state = ERROR; uint32_t dma_flag; - + /* reset all core internal registers located in CLK_TX and CLK_RX */ ENET_DMA_BCTL |= ENET_DMA_BCTL_SWR; - + /* wait for reset operation complete */ - do{ + do { dma_flag = (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR); timeout++; - }while((RESET != dma_flag) && (ENET_DELAY_TO != timeout)); + } while((RESET != dma_flag) && (ENET_DELAY_TO != timeout)); - /* reset operation complete */ - if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)){ + /* reset operation complete */ + if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)) { enet_state = SUCCESS; } - + return enet_state; } @@ -665,19 +663,19 @@ uint32_t enet_rxframe_size_get(void) { uint32_t size = 0U; uint32_t status; - + /* get rdes0 information of current RxDMA descriptor */ status = dma_current_rxdesc->status; - + /* if the desciptor is owned by DMA */ - if((uint32_t)RESET != (status & ENET_RDES0_DAV)){ + if((uint32_t)RESET != (status & ENET_RDES0_DAV)) { return 0U; } - + /* if has any error, or the frame uses two or more descriptors */ if((((uint32_t)RESET) != (status & ENET_RDES0_ERRS)) || - (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) || - (((uint32_t)RESET) == (status & ENET_RDES0_FDES))){ + (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) || + (((uint32_t)RESET) == (status & ENET_RDES0_FDES))) { /* drop current receive frame */ enet_rxframe_drop(); @@ -686,44 +684,44 @@ uint32_t enet_rxframe_size_get(void) #ifdef SELECT_DESCRIPTORS_ENHANCED_MODE /* if is an ethernet-type frame, and IP frame payload error occurred */ if(((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FRMT) && - ((uint32_t)RESET) != (dma_current_rxdesc->extended_status & ENET_RDES4_IPPLDERR)){ - /* drop current receive frame */ - enet_rxframe_drop(); + ((uint32_t)RESET) != (dma_current_rxdesc->extended_status & ENET_RDES4_IPPLDERR)) { + /* drop current receive frame */ + enet_rxframe_drop(); return 1U; } -#else +#else /* if is an ethernet-type frame, and IP frame payload error occurred */ if((((uint32_t)RESET) != (status & ENET_RDES0_FRMT)) && - (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))){ - /* drop current receive frame */ - enet_rxframe_drop(); + (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))) { + /* drop current receive frame */ + enet_rxframe_drop(); return 1U; - } -#endif + } +#endif /* if CPU owns current descriptor, no error occured, the frame uses only one descriptor */ if((((uint32_t)RESET) == (status & ENET_RDES0_DAV)) && - (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) && - (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) && - (((uint32_t)RESET) != (status & ENET_RDES0_FDES))){ + (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (status & ENET_RDES0_FDES))) { /* get the size of the received data including CRC */ size = GET_RDES0_FRML(status); - /* substract the CRC size */ + /* substract the CRC size */ size = size - 4U; - - /* if is a type frame, and CRC is not included in forwarding frame */ - if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))){ + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))) { size = size + 4U; } - }else{ + } else { enet_unknow_err++; enet_rxframe_drop(); return 1U; } - - /* return packet size */ + + /* return packet size */ return size; } @@ -741,62 +739,62 @@ void enet_descriptors_chain_init(enet_dmadirection_enum direction) uint32_t num = 0U, count = 0U, maxsize = 0U; uint32_t desc_status = 0U, desc_bufsize = 0U; enet_descriptors_struct *desc, *desc_tab; - uint8_t *buf; + uint8_t *buf; /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; maxsize = ENET_TXBUF_SIZE; - + /* select chain mode */ desc_status = ENET_TDES0_TCHM; - + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; maxsize = ENET_RXBUF_SIZE; - + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* select receive chained mode and set buffer1 size */ desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; - + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; - dma_current_rxdesc = desc_tab; + dma_current_rxdesc = desc_tab; } dma_current_ptp_rxdesc = NULL; dma_current_ptp_txdesc = NULL; - - /* configure each descriptor */ - for(num=0U; num < count; num++){ + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; + desc->status = desc_status; desc->control_buffer_size = desc_bufsize; desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + /* if is not the last descriptor */ - if(num < (count - 1U)){ + if(num < (count - 1U)) { /* configure the next descriptor address */ desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); - }else{ - /* when it is the last descriptor, the next descriptor address - equals to first descriptor address in descriptor table */ - desc->buffer2_next_desc_addr = (uint32_t) desc_tab; + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t) desc_tab; } - } + } } /*! @@ -814,64 +812,64 @@ void enet_descriptors_ring_init(enet_dmadirection_enum direction) uint32_t desc_status = 0U, desc_bufsize = 0U; enet_descriptors_struct *desc; enet_descriptors_struct *desc_tab; - uint8_t *buf; - + uint8_t *buf; + /* configure descriptor skip length */ ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); - + /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; - maxsize = ENET_TXBUF_SIZE; - + maxsize = ENET_TXBUF_SIZE; + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; - maxsize = ENET_RXBUF_SIZE; - + maxsize = ENET_RXBUF_SIZE; + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* set buffer1 size */ desc_bufsize = ENET_RXBUF_SIZE; - - /* configure DMA Rx descriptor table address register */ + + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; - dma_current_rxdesc = desc_tab; + dma_current_rxdesc = desc_tab; } dma_current_ptp_rxdesc = NULL; dma_current_ptp_txdesc = NULL; - - /* configure each descriptor */ - for(num=0U; num < count; num++){ + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; - desc->control_buffer_size = desc_bufsize; - desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + /* when it is the last descriptor */ - if(num == (count - 1U)){ - if (ENET_DMA_TX == direction){ - /* configure transmit end of ring mode */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ desc->status |= ENET_TDES0_TERM; - }else{ + } else { /* configure receive end of ring mode */ desc->control_buffer_size |= ENET_RDES1_RERM; } } - } + } } /*! @@ -884,69 +882,69 @@ void enet_descriptors_ring_init(enet_dmadirection_enum direction) ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize) { uint32_t offset = 0U, size = 0U; - + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ - return ERROR; + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + return ERROR; } - + /* if buffer pointer is null, indicates that users has copied data in application */ - if(NULL != buffer){ + if(NULL != buffer) { /* if no error occurs, and the frame uses only one descriptor */ - if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && - (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && - (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ + if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { /* get the frame length except CRC */ size = GET_RDES0_FRML(dma_current_rxdesc->status); size = size - 4U; - - /* if is a type frame, and CRC is not included in forwarding frame */ - if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { size = size + 4U; } - + /* to avoid situation that the frame size exceeds the buffer length */ - if(size > bufsize){ + if(size > bufsize) { return ERROR; } - + /* copy data from Rx buffer to application buffer */ - for(offset = 0U; offsetbuffer1_addr) + offset)); + for(offset = 0U; offset < size; offset++) { + (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_rxdesc->buffer1_addr) + offset)); } - - }else{ + + } else { /* return ERROR */ return ERROR; } } /* enable reception, descriptor is owned by DMA */ - dma_current_rxdesc->status = ENET_RDES0_DAV; - + dma_current_rxdesc->status = ENET_RDES0_DAV; + /* check Rx buffer unavailable flag status */ - if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + if((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)) { /* clear RBU flag */ ENET_DMA_STAT = ENET_DMA_STAT_RBU; /* resume DMA reception by writing to the RPEN register*/ ENET_DMA_RPEN = 0U; } - - /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ /* chained mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ - dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); - }else{ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); + } else { /* ring mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); - }else{ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); } } - + return SUCCESS; } @@ -962,55 +960,55 @@ ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length) { uint32_t offset = 0U; uint32_t dma_tbu_flag, dma_tu_flag; - + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { return ERROR; } - + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ - if(length > ENET_MAX_FRAME_SIZE){ + if(length > ENET_MAX_FRAME_SIZE) { return ERROR; - } - + } + /* if buffer pointer is null, indicates that users has handled data in application */ - if(NULL != buffer){ + if(NULL != buffer) { /* copy frame data from application buffer to Tx buffer */ - for(offset = 0U; offset < length; offset++){ - (*(__IO uint8_t *) (uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + for(offset = 0U; offset < length; offset++) { + (*(__IO uint8_t *)(uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); } } - + /* set the frame length */ dma_current_txdesc->control_buffer_size = length; - /* set the segment of frame, frame is transmitted in one descriptor */ + /* set the segment of frame, frame is transmitted in one descriptor */ dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; /* enable the DMA transmission */ dma_current_txdesc->status |= ENET_TDES0_DAV; - + /* check Tx buffer unavailable flag status */ - dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); - - if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { /* clear TBU and TU flag */ ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); /* resume DMA transmission by writing to the TPEN register*/ ENET_DMA_TPEN = 0U; } - - /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ /* chained mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ - dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr); - }else{ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_txdesc->buffer2_next_desc_addr); + } else { /* ring mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); - }else{ + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); + dma_current_txdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL))); } } @@ -1060,7 +1058,7 @@ void enet_disable(void) } /*! - \brief configure MAC address + \brief configure MAC address \param[in] mac_addr: select which MAC address will be set, refer to enet_macaddress_enum only one parameter can be selected which is shown as below \arg ENET_MAC_ADDRESS0: set MAC address 0 filter @@ -1068,10 +1066,10 @@ void enet_disable(void) \arg ENET_MAC_ADDRESS2: set MAC address 2 filter \arg ENET_MAC_ADDRESS3: set MAC address 3 filter \param[in] paddr: the buffer pointer which stores the MAC address - (little-ending store, such as MAC address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + (little-ending store, such as MAC address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) \param[out] none \retval none -*/ +*/ void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]) { REG32(ENET_ADDRH_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRH(paddr); @@ -1079,7 +1077,7 @@ void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]) } /*! - \brief get MAC address + \brief get MAC address \param[in] mac_addr: select which MAC address will be get, refer to enet_macaddress_enum only one parameter can be selected which is shown as below \arg ENET_MAC_ADDRESS0: get MAC address 0 filter @@ -1087,9 +1085,9 @@ void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]) \arg ENET_MAC_ADDRESS2: get MAC address 2 filter \arg ENET_MAC_ADDRESS3: get MAC address 3 filter \param[out] paddr: the buffer pointer which is stored the MAC address - (little-ending store, such as mac address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + (little-ending store, such as mac address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) \retval none -*/ +*/ void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]) { paddr[0] = ENET_GET_MACADDR(mac_addr, 0U); @@ -1101,12 +1099,12 @@ void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]) } /*! - \brief get the ENET MAC/MSC/PTP/DMA status flag + \brief get the ENET MAC/MSC/PTP/DMA status flag \param[in] enet_flag: ENET status flag, refer to enet_flag_enum, only one parameter can be selected which is shown as below - \arg ENET_MAC_FLAG_MPKR: magic packet received flag + \arg ENET_MAC_FLAG_MPKR: magic packet received flag \arg ENET_MAC_FLAG_WUFR: wakeup frame received flag - \arg ENET_MAC_FLAG_FLOWCONTROL: flow control status flag + \arg ENET_MAC_FLAG_FLOWCONTROL: flow control status flag \arg ENET_MAC_FLAG_WUM: WUM status flag \arg ENET_MAC_FLAG_MSC: MSC status flag \arg ENET_MAC_FLAG_MSCR: MSC receive status flag @@ -1146,15 +1144,15 @@ void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]) */ FlagStatus enet_flag_get(enet_flag_enum enet_flag) { - if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))){ + if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear the ENET DMA status flag + \brief clear the ENET DMA status flag \param[in] enet_flag: ENET DMA flag clear, refer to enet_flag_clear_enum only one parameter can be selected which is shown as below \arg ENET_DMA_FLAG_TS_CLR: transmit status flag clear @@ -1182,7 +1180,7 @@ void enet_flag_clear(enet_flag_clear_enum enet_flag) } /*! - \brief enable ENET MAC/MSC/DMA interrupt + \brief enable ENET MAC/MSC/DMA interrupt \param[in] enet_int: ENET interrupt,, refer to enet_int_enum only one parameter can be selected which is shown as below \arg ENET_MAC_INT_WUMIM: WUM interrupt mask @@ -1213,17 +1211,17 @@ void enet_flag_clear(enet_flag_clear_enum enet_flag) */ void enet_interrupt_enable(enet_int_enum enet_int) { - if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)) { /* ENET_DMA_INTEN register interrupt */ ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); - }else{ + } else { /* other INTMSK register interrupt */ ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); } } /*! - \brief disable ENET MAC/MSC/DMA interrupt + \brief disable ENET MAC/MSC/DMA interrupt \param[in] enet_int: ENET interrupt, refer to enet_int_enum only one parameter can be selected which is shown as below \arg ENET_MAC_INT_WUMIM: WUM interrupt mask @@ -1254,17 +1252,17 @@ void enet_interrupt_enable(enet_int_enum enet_int) */ void enet_interrupt_disable(enet_int_enum enet_int) { - if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)){ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)) { /* ENET_DMA_INTEN register interrupt */ ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); - }else{ + } else { /* other INTMSK register interrupt */ ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); } } /*! - \brief get ENET MAC/MSC/DMA interrupt flag + \brief get ENET MAC/MSC/DMA interrupt flag \param[in] int_flag: ENET interrupt flag, refer to enet_int_flag_enum only one parameter can be selected which is shown as below \arg ENET_MAC_INT_FLAG_WUM: WUM status flag @@ -1301,15 +1299,15 @@ void enet_interrupt_disable(enet_int_enum enet_int) */ FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag) { - if(RESET != (ENET_REG_VAL(int_flag) & BIT(ENET_BIT_POS(int_flag)))){ + if(RESET != (ENET_REG_VAL(int_flag) & BIT(ENET_BIT_POS(int_flag)))) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear ENET DMA interrupt flag + \brief clear ENET DMA interrupt flag \param[in] int_flag_clear: clear ENET interrupt flag, refer to enet_int_flag_clear_enum only one parameter can be selected which is shown as below \arg ENET_DMA_INT_FLAG_TS_CLR: transmit status flag @@ -1356,7 +1354,7 @@ void enet_tx_enable(void) \retval none */ void enet_tx_disable(void) -{ +{ ENET_DMA_CTL &= ~ENET_DMA_CTL_STE; enet_txfifo_flush(); ENET_MAC_CFG &= ~ENET_MAC_CFG_TEN; @@ -1387,10 +1385,10 @@ void enet_rx_disable(void) } /*! - \brief put registers value into the application buffer + \brief put registers value into the application buffer \param[in] type: register type which will be get, refer to enet_registers_type_enum, only one parameter can be selected which is shown as below - \arg ALL_MAC_REG: get the registers within the offset scope between ENET_MAC_CFG and ENET_MAC_FCTH + \arg ALL_MAC_REG: get the registers within the offset scope between ENET_MAC_CFG and ENET_MAC_FCTH \arg ALL_MSC_REG: get the registers within the offset scope between ENET_MSC_CTL and ENET_MSC_RGUFCNT \arg ALL_PTP_REG: get the registers within the offset scope between ENET_PTP_TSCTL and ENET_PTP_PPSCTL \arg ALL_DMA_REG: get the registers within the offset scope between ENET_DMA_BCTL and ENET_DMA_CRBADDR @@ -1401,22 +1399,22 @@ void enet_rx_disable(void) void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num) { uint32_t offset = 0U, max = 0U, limit = 0U; - + offset = (uint32_t)type; max = (uint32_t)type + num; - limit = sizeof(enet_reg_tab)/sizeof(uint16_t); - + limit = sizeof(enet_reg_tab) / sizeof(uint16_t); + /* prevent element in this array is out of range */ - if(max > limit){ + if(max > limit) { max = limit; } - - for(; offset < max; offset++){ + + for(; offset < max; offset++) { /* get value of the corresponding register */ - *preg = REG32((ENET) + enet_reg_tab[offset]); + *preg = REG32((ENET) + enet_reg_tab[offset]); preg++; } -} +} /*! \brief get the enet debug status from the debug register @@ -1440,8 +1438,8 @@ void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t uint32_t enet_debug_status_get(uint32_t mac_debug) { uint32_t temp_state = 0U; - - switch(mac_debug){ + + switch(mac_debug) { case ENET_RX_ASYNCHRONOUS_FIFO_STATE: temp_state = GET_MAC_DBG_RXAFS(ENET_MAC_DBG); break; @@ -1458,16 +1456,16 @@ uint32_t enet_debug_status_get(uint32_t mac_debug) temp_state = GET_MAC_DBG_TXFRS(ENET_MAC_DBG); break; default: - if(RESET != (ENET_MAC_DBG & mac_debug)){ + if(RESET != (ENET_MAC_DBG & mac_debug)) { temp_state = 0x1U; } - break; + break; } return temp_state; } /*! - \brief enable the MAC address filter + \brief enable the MAC address filter \param[in] mac_addr: select which MAC address will be enable, refer to enet_macaddress_enum \arg ENET_MAC_ADDRESS1: enable MAC address 1 filter \arg ENET_MAC_ADDRESS2: enable MAC address 2 filter @@ -1481,7 +1479,7 @@ void enet_address_filter_enable(enet_macaddress_enum mac_addr) } /*! - \brief disable the MAC address filter + \brief disable the MAC address filter \param[in] mac_addr: select which MAC address will be disable, refer to enet_macaddress_enum only one parameter can be selected which is shown as below \arg ENET_MAC_ADDRESS1: disable MAC address 1 filter @@ -1496,7 +1494,7 @@ void enet_address_filter_disable(enet_macaddress_enum mac_addr) } /*! - \brief configure the MAC address filter + \brief configure the MAC address filter \param[in] mac_addr: select which MAC address will be configured, refer to enet_macaddress_enum only one parameter can be selected which is shown as below \arg ENET_MAC_ADDRESS1: configure MAC address 1 filter @@ -1505,7 +1503,7 @@ void enet_address_filter_disable(enet_macaddress_enum mac_addr) \param[in] addr_mask: select which MAC address bytes will be mask one or more parameters can be selected which are shown as below \arg ENET_ADDRESS_MASK_BYTE0: mask ENET_MAC_ADDR1L[7:0] bits - \arg ENET_ADDRESS_MASK_BYTE1: mask ENET_MAC_ADDR1L[15:8] bits + \arg ENET_ADDRESS_MASK_BYTE1: mask ENET_MAC_ADDR1L[15:8] bits \arg ENET_ADDRESS_MASK_BYTE2: mask ENET_MAC_ADDR1L[23:16] bits \arg ENET_ADDRESS_MASK_BYTE3: mask ENET_MAC_ADDR1L [31:24] bits \arg ENET_ADDRESS_MASK_BYTE4: mask ENET_MAC_ADDR1H [7:0] bits @@ -1520,7 +1518,7 @@ void enet_address_filter_disable(enet_macaddress_enum mac_addr) void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type) { uint32_t reg; - + /* get the address filter register value which is to be configured */ reg = REG32(ENET_ADDRH_BASE + mac_addr); @@ -1535,55 +1533,55 @@ void enet_address_filter_config(enet_macaddress_enum mac_addr, uint32_t addr_mas \param[in] none \param[out] none \retval ErrStatus: SUCCESS or ERROR -*/ +*/ ErrStatus enet_phy_config(void) { uint32_t ahbclk; uint32_t reg; uint16_t phy_value; ErrStatus enet_state = ERROR; - + /* clear the previous MDC clock */ reg = ENET_MAC_PHY_CTL; reg &= ~ENET_MAC_PHY_CTL_CLR; /* get the HCLK frequency */ ahbclk = rcu_clock_freq_get(CK_AHB); - + /* configure MDC clock according to HCLK frequency range */ - if(ENET_RANGE(ahbclk, 20000000U, 35000000U)){ + if(ENET_RANGE(ahbclk, 20000000U, 35000000U)) { reg |= ENET_MDC_HCLK_DIV16; - }else if(ENET_RANGE(ahbclk, 35000000U, 60000000U)){ + } else if(ENET_RANGE(ahbclk, 35000000U, 60000000U)) { reg |= ENET_MDC_HCLK_DIV26; - }else if(ENET_RANGE(ahbclk, 60000000U, 100000000U)){ + } else if(ENET_RANGE(ahbclk, 60000000U, 100000000U)) { reg |= ENET_MDC_HCLK_DIV42; - }else if(ENET_RANGE(ahbclk, 100000000U, 150000000U)){ + } else if(ENET_RANGE(ahbclk, 100000000U, 150000000U)) { reg |= ENET_MDC_HCLK_DIV62; - }else if((ENET_RANGE(ahbclk, 150000000U, 200000000U))||(200000000U == ahbclk)){ - reg |= ENET_MDC_HCLK_DIV102; - }else{ + } else if((ENET_RANGE(ahbclk, 150000000U, 240000000U)) || (240000000U == ahbclk)) { + reg |= ENET_MDC_HCLK_DIV102; + } else { return enet_state; } ENET_MAC_PHY_CTL = reg; /* reset PHY */ phy_value = PHY_RESET; - if(ERROR == (enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){ + if(ERROR == (enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value))) { return enet_state; } - /* PHY reset need some time */ + /* PHY reset need some time */ _ENET_DELAY_(ENET_DELAY_TO); - + /* check whether PHY reset is complete */ - if(ERROR == (enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){ + if(ERROR == (enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))) { return enet_state; } /* PHY reset complete */ - if(RESET == (phy_value & PHY_RESET)){ + if(RESET == (phy_value & PHY_RESET)) { enet_state = SUCCESS; } - + return enet_state; } @@ -1594,7 +1592,7 @@ ErrStatus enet_phy_config(void) \arg ENET_PHY_READ: read data from phy register \param[in] phy_address: 0x0000 - 0x001F \param[in] phy_reg: 0x0000 - 0x001F - \param[in] pvalue: the value will be written to the PHY register in ENET_PHY_WRITE direction + \param[in] pvalue: the value will be written to the PHY register in ENET_PHY_WRITE direction \param[out] pvalue: the value will be read from the PHY register in ENET_PHY_READ direction \retval ErrStatus: SUCCESS or ERROR */ @@ -1604,34 +1602,33 @@ ErrStatus enet_phy_write_read(enet_phydirection_enum direction, uint16_t phy_add uint32_t timeout = 0U; ErrStatus enet_state = ERROR; - /* configure ENET_MAC_PHY_CTL with write/read operation */ + /* configure ENET_MAC_PHY_CTL with write/read operation */ reg = ENET_MAC_PHY_CTL; reg &= ~(ENET_MAC_PHY_CTL_PB | ENET_MAC_PHY_CTL_PW | ENET_MAC_PHY_CTL_PR | ENET_MAC_PHY_CTL_PA); - reg |= (direction | MAC_PHY_CTL_PR(phy_reg) | MAC_PHY_CTL_PA(phy_address) | ENET_MAC_PHY_CTL_PB); + reg |= (direction | MAC_PHY_CTL_PR(phy_reg) | MAC_PHY_CTL_PA(phy_address) | ENET_MAC_PHY_CTL_PB); /* if do the write operation, write value to the register */ - if(ENET_PHY_WRITE == direction){ - ENET_MAC_PHY_DATA = *pvalue; + if(ENET_PHY_WRITE == direction) { + ENET_MAC_PHY_DATA = *pvalue; } - + /* do PHY write/read operation, and wait the operation complete */ ENET_MAC_PHY_CTL = reg; - do{ + do { phy_flag = (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB); timeout++; - } - while((RESET != phy_flag) && (ENET_DELAY_TO != timeout)); + } while((RESET != phy_flag) && (ENET_DELAY_TO != timeout)); - /* write/read operation complete */ - if(RESET == (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB)){ + /* write/read operation complete */ + if(RESET == (ENET_MAC_PHY_CTL & ENET_MAC_PHY_CTL_PB)) { enet_state = SUCCESS; } - /* if do the read operation, get value from the register */ - if(ENET_PHY_READ == direction){ - *pvalue = (uint16_t)ENET_MAC_PHY_DATA; + /* if do the read operation, get value from the register */ + if(ENET_PHY_READ == direction) { + *pvalue = (uint16_t)ENET_MAC_PHY_DATA; } - + return enet_state; } @@ -1647,7 +1644,7 @@ ErrStatus enet_phyloopback_enable(void) ErrStatus phy_state = ERROR; /* get the PHY configuration to update it */ - enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); /* enable the PHY loopback mode */ temp_phy |= PHY_LOOPBACK; @@ -1670,7 +1667,7 @@ ErrStatus enet_phyloopback_disable(void) ErrStatus phy_state = ERROR; /* get the PHY configuration to update it */ - enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); /* disable the PHY loopback mode */ temp_phy &= (uint16_t)~PHY_LOOPBACK; @@ -1695,10 +1692,10 @@ ErrStatus enet_phyloopback_disable(void) void enet_forward_feature_enable(uint32_t feature) { uint32_t mask; - + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); ENET_MAC_CFG |= mask; - + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); ENET_DMA_CTL |= (mask >> 2); } @@ -1717,15 +1714,15 @@ void enet_forward_feature_enable(uint32_t feature) void enet_forward_feature_disable(uint32_t feature) { uint32_t mask; - + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); ENET_MAC_CFG &= ~mask; - + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); ENET_DMA_CTL &= ~(mask >> 2); } - -/*! + +/*! \brief enable ENET fliter feature \param[in] feature: the feature of ENET fliter mode one or more parameters can be selected which are shown as below @@ -1770,18 +1767,18 @@ void enet_fliter_feature_disable(uint32_t feature) \param[out] none \retval ErrStatus: ERROR or SUCCESS */ -ErrStatus enet_pauseframe_generate(void) -{ - ErrStatus enet_state =ERROR; +ErrStatus enet_pauseframe_generate(void) +{ + ErrStatus enet_state = ERROR; uint32_t temp = 0U; /* in full-duplex mode, must make sure this bit is 0 before writing register */ temp = ENET_MAC_FCTL & ENET_MAC_FCTL_FLCBBKPA; - if(RESET == temp){ + if(RESET == temp) { ENET_MAC_FCTL |= ENET_MAC_FCTL_FLCBBKPA; enet_state = SUCCESS; } - return enet_state; + return enet_state; } /*! @@ -1790,7 +1787,7 @@ ErrStatus enet_pauseframe_generate(void) only one parameter can be selected which is shown as below \arg ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT: besides the unique multicast address, MAC can also use the MAC0 address to detecting pause frame - \arg ENET_UNIQUE_PAUSEDETECT: only the unique multicast address for pause frame which is specified + \arg ENET_UNIQUE_PAUSEDETECT: only the unique multicast address for pause frame which is specified in IEEE802.3 can be detected \param[out] none \retval none @@ -1846,7 +1843,7 @@ void enet_pauseframe_config(uint32_t pausetime, uint32_t pause_threshold) */ void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active) { - ENET_MAC_FCTH = ((deactive | active) >> 8); + ENET_MAC_FCTH = ((deactive | active) >> 8); } /*! @@ -1862,7 +1859,7 @@ void enet_flowcontrol_threshold_config(uint32_t deactive, uint32_t active) */ void enet_flowcontrol_feature_enable(uint32_t feature) { - if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { ENET_MAC_FCTL &= ~ENET_ZERO_QUANTA_PAUSE; } feature &= ~ENET_ZERO_QUANTA_PAUSE; @@ -1882,7 +1879,7 @@ void enet_flowcontrol_feature_enable(uint32_t feature) */ void enet_flowcontrol_feature_disable(uint32_t feature) { - if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)){ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { ENET_MAC_FCTL |= ENET_ZERO_QUANTA_PAUSE; } feature &= ~ENET_ZERO_QUANTA_PAUSE; @@ -1910,7 +1907,7 @@ uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction) } /*! - \brief poll the DMA transmission/reception enable by writing any value to the + \brief poll the DMA transmission/reception enable by writing any value to the ENET_DMA_TPEN/ENET_DMA_RPEN register, this will make the DMA to resume transmission/reception \param[in] direction: choose the direction of DMA process which users want to resume, refer to enet_dmadirection_enum only one parameter can be selected which is shown as below @@ -1921,15 +1918,15 @@ uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction) */ void enet_dmaprocess_resume(enet_dmadirection_enum direction) { - if(ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { ENET_DMA_TPEN = 0U; - }else{ + } else { ENET_DMA_RPEN = 0U; } } /*! - \brief check and recover the Rx process + \brief check and recover the Rx process \param[in] none \param[out] none \retval none @@ -1938,15 +1935,15 @@ void enet_rxprocess_check_recovery(void) { uint32_t status; - /* get DAV information of current RxDMA descriptor */ + /* get DAV information of current RxDMA descriptor */ status = dma_current_rxdesc->status; status &= ENET_RDES0_DAV; - - /* if current descriptor is owned by DMA, but the descriptor address mismatches with + + /* if current descriptor is owned by DMA, but the descriptor address mismatches with receive descriptor address pointer updated by RxDMA controller */ if((ENET_DMA_CRDADDR != ((uint32_t)dma_current_rxdesc)) && - (ENET_RDES0_DAV == status)){ - dma_current_rxdesc = (enet_descriptors_struct*)ENET_DMA_CRDADDR; + (ENET_RDES0_DAV == status)) { + dma_current_rxdesc = (enet_descriptors_struct *)ENET_DMA_CRDADDR; } } @@ -1961,19 +1958,19 @@ ErrStatus enet_txfifo_flush(void) uint32_t flush_state; uint32_t timeout = 0U; ErrStatus enet_state = ERROR; - + /* set the FTF bit for flushing transmit FIFO */ - ENET_DMA_CTL |= ENET_DMA_CTL_FTF; + ENET_DMA_CTL |= ENET_DMA_CTL_FTF; /* wait until the flush operation completes */ - do{ - flush_state = ENET_DMA_CTL & ENET_DMA_CTL_FTF; + do { + flush_state = ENET_DMA_CTL & ENET_DMA_CTL_FTF; timeout++; - }while((RESET != flush_state) && (timeout < ENET_DELAY_TO)); + } while((RESET != flush_state) && (timeout < ENET_DELAY_TO)); /* return ERROR due to timeout */ - if(RESET == flush_state){ + if(RESET == flush_state) { enet_state = SUCCESS; } - + return enet_state; } @@ -1989,14 +1986,14 @@ ErrStatus enet_txfifo_flush(void) \arg ENET_TX_CURRENT_DESC: the start descriptor address of the current transmit descriptor read by the TxDMA controller \arg ENET_TX_CURRENT_BUFFER: the current transmit buffer address being read by the TxDMA controller - \param[out] none + \param[out] none \retval address value */ uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get) { uint32_t reval = 0U; - reval = REG32((ENET) +(uint32_t)addr_get); + reval = REG32((ENET) + (uint32_t)addr_get); return reval; } @@ -2018,36 +2015,36 @@ uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate { uint32_t reval = 0xFFFFFFFFU; - switch(info_get){ + switch(info_get) { case RXDESC_BUFFER_1_SIZE: reval = GET_RDES1_RB1S(desc->control_buffer_size); break; case RXDESC_BUFFER_2_SIZE: reval = GET_RDES1_RB2S(desc->control_buffer_size); - break; - case RXDESC_FRAME_LENGTH: + break; + case RXDESC_FRAME_LENGTH: reval = GET_RDES0_FRML(desc->status); - if(reval > 4U){ + if(reval > 4U) { reval = reval - 4U; - - /* if is a type frame, and CRC is not included in forwarding frame */ - if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (desc->status & ENET_RDES0_FRMT))){ + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (desc->status & ENET_RDES0_FRMT))) { reval = reval + 4U; - } - }else{ + } + } else { reval = 0U; } - + break; - case RXDESC_BUFFER_1_ADDR: - reval = desc->buffer1_addr; + case RXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; break; - case TXDESC_BUFFER_1_ADDR: - reval = desc->buffer1_addr; + case TXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; break; - case TXDESC_COLLISION_COUNT: + case TXDESC_COLLISION_COUNT: reval = GET_TDES0_COCNT(desc->status); - break; + break; default: break; } @@ -2064,7 +2061,7 @@ uint32_t enet_desc_information_get(enet_descriptors_struct *desc, enet_descstate void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) { uint32_t temp_counter = 0U; - + temp_counter = ENET_DMA_MFBOCNT; *rxfifo_drop = GET_DMA_MFBOCNT_MSFA(temp_counter); *rxdma_drop = GET_DMA_MFBOCNT_MSFC(temp_counter); @@ -2075,7 +2072,7 @@ void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) \param[in] desc: the descriptor pointer which users want to get flag \param[in] desc_flag: the bit flag of ENET DMA descriptor only one parameter can be selected which is shown as below - \arg ENET_TDES0_DB: deferred + \arg ENET_TDES0_DB: deferred \arg ENET_TDES0_UFE: underflow error \arg ENET_TDES0_EXD: excessive deferral \arg ENET_TDES0_VFRM: VLAN frame @@ -2088,18 +2085,18 @@ void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) \arg ENET_TDES0_JT: jabber timeout \arg ENET_TDES0_ES: error summary \arg ENET_TDES0_IPHE: IP header error - \arg ENET_TDES0_TTMSS: transmit timestamp status + \arg ENET_TDES0_TTMSS: transmit timestamp status \arg ENET_TDES0_TCHM: the second address chained mode \arg ENET_TDES0_TERM: transmit end of ring mode \arg ENET_TDES0_TTSEN: transmit timestamp function enable - \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DPAD: disable adding pad \arg ENET_TDES0_DCRC: disable CRC \arg ENET_TDES0_FSG: first segment \arg ENET_TDES0_LSG: last segment \arg ENET_TDES0_INTC: interrupt on completion \arg ENET_TDES0_DAV: DAV bit - - \arg ENET_RDES0_PCERR: payload checksum error + + \arg ENET_RDES0_PCERR: payload checksum error \arg ENET_RDES0_EXSV: extended status valid \arg ENET_RDES0_CERR: CRC error \arg ENET_RDES0_DBERR: dribble bit error @@ -2112,11 +2109,11 @@ void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) \arg ENET_RDES0_LDES: last descriptor \arg ENET_RDES0_FDES: first descriptor \arg ENET_RDES0_VTAG: VLAN tag - \arg ENET_RDES0_OERR: overflow error + \arg ENET_RDES0_OERR: overflow error \arg ENET_RDES0_LERR: length error \arg ENET_RDES0_SAFF: SA filter fail \arg ENET_RDES0_DERR: descriptor error - \arg ENET_RDES0_ERRS: error summary + \arg ENET_RDES0_ERRS: error summary \arg ENET_RDES0_DAFF: destination address filter fail \arg ENET_RDES0_DAV: descriptor available \param[out] none @@ -2125,8 +2122,8 @@ void enet_missed_frame_counter_get(uint32_t *rxfifo_drop, uint32_t *rxdma_drop) FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag) { FlagStatus enet_flag = RESET; - - if ((uint32_t)RESET != (desc->status & desc_flag)){ + + if((uint32_t)RESET != (desc->status & desc_flag)) { enet_flag = SET; } @@ -2143,13 +2140,13 @@ FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag) \arg ENET_TDES0_TCHM: the second address chained mode \arg ENET_TDES0_TERM: transmit end of ring mode \arg ENET_TDES0_TTSEN: transmit timestamp function enable - \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DPAD: disable adding pad \arg ENET_TDES0_DCRC: disable CRC \arg ENET_TDES0_FSG: first segment \arg ENET_TDES0_LSG: last segment \arg ENET_TDES0_INTC: interrupt on completion \arg ENET_TDES0_DAV: DAV bit - \arg ENET_RDES0_DAV: descriptor available + \arg ENET_RDES0_DAV: descriptor available \param[out] none \retval none */ @@ -2168,13 +2165,13 @@ void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag) \arg ENET_TDES0_TCHM: the second address chained mode \arg ENET_TDES0_TERM: transmit end of ring mode \arg ENET_TDES0_TTSEN: transmit timestamp function enable - \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DPAD: disable adding pad \arg ENET_TDES0_DCRC: disable CRC \arg ENET_TDES0_FSG: first segment \arg ENET_TDES0_LSG: last segment \arg ENET_TDES0_INTC: interrupt on completion \arg ENET_TDES0_DAV: DAV bit - \arg ENET_RDES0_DAV: descriptor available + \arg ENET_RDES0_DAV: descriptor available \param[out] none \retval none */ @@ -2184,7 +2181,7 @@ void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag) } /*! - \brief when receiving completed, set RS bit in ENET_DMA_STAT register will immediately set + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will immediately set \param[in] desc: the descriptor pointer which users want to configure \param[out] none \retval none @@ -2195,7 +2192,7 @@ void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct * } /*! - \brief when receiving completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time \param[in] desc: the descriptor pointer which users want to configure \param[in] delay_time: delay a time of 256*delay_time HCLK(0x00000000 - 0x000000FF) \param[out] none @@ -2216,36 +2213,36 @@ void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc void enet_rxframe_drop(void) { /* enable reception, descriptor is owned by DMA */ - dma_current_rxdesc->status = ENET_RDES0_DAV; - + dma_current_rxdesc->status = ENET_RDES0_DAV; + /* chained mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ - if(NULL != dma_current_ptp_rxdesc){ - dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr); + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + if(NULL != dma_current_ptp_rxdesc) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->buffer2_next_desc_addr); /* if it is the last ptp descriptor */ - if(0U != dma_current_ptp_rxdesc->status){ + if(0U != dma_current_ptp_rxdesc->status) { /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ - dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); - }else{ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { /* ponter to the next ptp descriptor */ dma_current_ptp_rxdesc++; } - }else{ - dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); + } else { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); } - - }else{ - /* ring mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); - if(NULL != dma_current_ptp_rxdesc){ - dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR); + if(NULL != dma_current_ptp_rxdesc) { + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); } - }else{ + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); - if(NULL != dma_current_ptp_rxdesc){ + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + if(NULL != dma_current_ptp_rxdesc) { dma_current_ptp_rxdesc++; } } @@ -2301,8 +2298,8 @@ void enet_dma_feature_disable(uint32_t feature) uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status) { uint32_t reval = 0xFFFFFFFFU; - - switch (desc_status){ + + switch(desc_status) { case ENET_RDES4_IPPLDT: reval = GET_RDES4_IPPLDT(desc->extended_status); break; @@ -2310,13 +2307,13 @@ uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_ reval = GET_RDES4_PTPMT(desc->extended_status); break; default: - if ((uint32_t)RESET != (desc->extended_status & desc_status)){ + if((uint32_t)RESET != (desc->extended_status & desc_status)) { reval = 1U; - }else{ + } else { reval = 0U; - } + } } - + return reval; } @@ -2346,59 +2343,59 @@ void enet_ptp_enhanced_descriptors_chain_init(enet_dmadirection_enum direction) uint32_t desc_status = 0U, desc_bufsize = 0U; enet_descriptors_struct *desc, *desc_tab; uint8_t *buf; - + /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; - maxsize = ENET_TXBUF_SIZE; - + maxsize = ENET_TXBUF_SIZE; + /* select chain mode, and enable transmit timestamp function */ desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; - + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; - maxsize = ENET_RXBUF_SIZE; - + maxsize = ENET_RXBUF_SIZE; + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* select receive chained mode and set buffer1 size */ desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; - + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; - dma_current_rxdesc = desc_tab; + dma_current_rxdesc = desc_tab; } - - /* configuration each descriptor */ - for(num = 0U; num < count; num++){ + + /* configuration each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; + desc->status = desc_status; desc->control_buffer_size = desc_bufsize; desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + /* if is not the last descriptor */ - if(num < (count - 1U)){ + if(num < (count - 1U)) { /* configure the next descriptor address */ desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); - }else{ - /* when it is the last descriptor, the next descriptor address - equals to first descriptor address in descriptor table */ - desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; } - } + } } /*! @@ -2416,69 +2413,69 @@ void enet_ptp_enhanced_descriptors_ring_init(enet_dmadirection_enum direction) uint32_t desc_status = 0U, desc_bufsize = 0U; enet_descriptors_struct *desc; enet_descriptors_struct *desc_tab; - uint8_t *buf; - + uint8_t *buf; + /* configure descriptor skip length */ ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); - + /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; - maxsize = ENET_TXBUF_SIZE; + maxsize = ENET_TXBUF_SIZE; /* select ring mode, and enable transmit timestamp function */ desc_status = ENET_TDES0_TTSEN; - + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; - maxsize = ENET_RXBUF_SIZE; - + maxsize = ENET_RXBUF_SIZE; + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* set buffer1 size */ desc_bufsize = ENET_RXBUF_SIZE; - - /* configure DMA Rx descriptor table address register */ + + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; - dma_current_rxdesc = desc_tab; + dma_current_rxdesc = desc_tab; } - - /* configure each descriptor */ - for(num=0U; num < count; num++){ + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; - desc->control_buffer_size = desc_bufsize; - desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + /* when it is the last descriptor */ - if(num == (count - 1U)){ - if (ENET_DMA_TX == direction){ - /* configure transmit end of ring mode */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ desc->status |= ENET_TDES0_TERM; - }else{ + } else { /* configure receive end of ring mode */ desc->control_buffer_size |= ENET_RDES1_RERM; } } - } + } } /*! - \brief receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode + \brief receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode \param[in] bufsize: the size of buffer which is the parameter in function \param[out] buffer: pointer to the application buffer note -- if the input is NULL, user should copy data in application by himself @@ -2491,54 +2488,54 @@ ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, uint32_t offset = 0U, size = 0U; uint32_t timeout = 0U; uint32_t rdes0_tsv_flag; - + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ - return ERROR; + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + return ERROR; } - + /* if buffer pointer is null, indicates that users has copied data in application */ - if(NULL != buffer){ - /* if no error occurs, and the frame uses only one descriptor */ - if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && - ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && - ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ + if(NULL != buffer) { + /* if no error occurs, and the frame uses only one descriptor */ + if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { /* get the frame length except CRC */ size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; - /* if is a type frame, and CRC is not included in forwarding frame */ - if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { size = size + 4U; } - + /* to avoid situation that the frame size exceeds the buffer length */ - if(size > bufsize){ + if(size > bufsize) { return ERROR; } /* copy data from Rx buffer to application buffer */ - for(offset = 0; offset < size; offset++){ + for(offset = 0; offset < size; offset++) { (*(buffer + offset)) = (*(__IO uint8_t *)((dma_current_rxdesc->buffer1_addr) + offset)); } - }else{ + } else { return ERROR; } - } - + } + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ - if(NULL != timestamp){ + if(NULL != timestamp) { /* wait for ENET_RDES0_TSV flag to be set, the timestamp value is taken and write to the RDES6 and RDES7 */ - do{ + do { rdes0_tsv_flag = (dma_current_rxdesc->status & ENET_RDES0_TSV); timeout++; - }while ((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO)); - + } while((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { return ERROR; } - + /* clear the ENET_RDES0_TSV flag */ dma_current_rxdesc->status &= ~ENET_RDES0_TSV; /* get the timestamp value of the received frame */ @@ -2548,35 +2545,35 @@ ErrStatus enet_ptpframe_receive_enhanced_mode(uint8_t *buffer, uint32_t bufsize, /* enable reception, descriptor is owned by DMA */ dma_current_rxdesc->status = ENET_RDES0_DAV; - + /* check Rx buffer unavailable flag status */ - if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + if((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)) { /* Clear RBU flag */ ENET_DMA_STAT = ENET_DMA_STAT_RBU; /* resume DMA reception by writing to the RPEN register*/ ENET_DMA_RPEN = 0; } - - /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ /* chained mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ - dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr); - }else{ - /* ring mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); - }else{ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_rxdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_rxdesc = (enet_descriptors_struct *)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); } } - + return SUCCESS; } /*! - \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode \param[in] buffer: pointer on the application buffer note -- if the input is NULL, user should copy data in application by himself \param[in] length: the length of frame data to be transmitted @@ -2589,56 +2586,56 @@ ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t offset = 0; uint32_t dma_tbu_flag, dma_tu_flag; uint32_t tdes0_ttmss_flag; - uint32_t timeout = 0; - + uint32_t timeout = 0; + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { return ERROR; } - + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ - if(length > ENET_MAX_FRAME_SIZE){ + if(length > ENET_MAX_FRAME_SIZE) { return ERROR; - } + } /* if buffer pointer is null, indicates that users has handled data in application */ - if(NULL != buffer){ + if(NULL != buffer) { /* copy frame data from application buffer to Tx buffer */ - for(offset = 0; offset < length; offset++){ + for(offset = 0; offset < length; offset++) { (*(__IO uint8_t *)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); } } /* set the frame length */ dma_current_txdesc->control_buffer_size = length; - /* set the segment of frame, frame is transmitted in one descriptor */ + /* set the segment of frame, frame is transmitted in one descriptor */ dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; /* enable the DMA transmission */ dma_current_txdesc->status |= ENET_TDES0_DAV; /* check Tx buffer unavailable flag status */ - dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); - - if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { /* Clear TBU and TU flag */ ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); /* resume DMA transmission by writing to the TPEN register*/ ENET_DMA_TPEN = 0; } - + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ - if(NULL != timestamp){ + if(NULL != timestamp) { /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ - do{ + do { tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); timeout++; - }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); - + } while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { return ERROR; } - + /* clear the ENET_TDES0_TTMSS flag */ dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; /* get the timestamp value of the transmit frame */ @@ -2646,18 +2643,18 @@ ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, timestamp[1] = dma_current_txdesc->timestamp_high; } - /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ /* chained mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ - dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr); - }else{ - /* ring mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_txdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); - }else{ + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_txdesc = (enet_descriptors_struct*) ((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_txdesc = (enet_descriptors_struct *)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); } } @@ -2693,67 +2690,67 @@ void enet_ptp_normal_descriptors_chain_init(enet_dmadirection_enum direction, en uint32_t desc_status = 0U, desc_bufsize = 0U; enet_descriptors_struct *desc, *desc_tab; uint8_t *buf; - + /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; - maxsize = ENET_TXBUF_SIZE; - + maxsize = ENET_TXBUF_SIZE; + /* select chain mode, and enable transmit timestamp function */ desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; - + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; dma_current_ptp_txdesc = desc_ptptab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; - maxsize = ENET_RXBUF_SIZE; - + maxsize = ENET_RXBUF_SIZE; + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* select receive chained mode and set buffer1 size */ desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; - + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; dma_current_rxdesc = desc_tab; - dma_current_ptp_rxdesc = desc_ptptab; + dma_current_ptp_rxdesc = desc_ptptab; } - - /* configure each descriptor */ - for(num = 0U; num < count; num++){ + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; + desc->status = desc_status; desc->control_buffer_size = desc_bufsize; desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + /* if is not the last descriptor */ - if(num < (count - 1U)){ + if(num < (count - 1U)) { /* configure the next descriptor address */ desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); - }else{ - /* when it is the last descriptor, the next descriptor address - equals to first descriptor address in descriptor table */ - desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; } /* set desc_ptptab equal to desc_tab */ (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; - } - /* when it is the last ptp descriptor, preserve the first descriptor + } + /* when it is the last ptp descriptor, preserve the first descriptor address of desc_ptptab in ptp descriptor status */ - (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab; + (&desc_ptptab[num - 1U])->status = (uint32_t)desc_ptptab; } /*! @@ -2776,57 +2773,57 @@ void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, ene /* configure descriptor skip length */ ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL; ENET_DMA_BCTL |= DMA_BCTL_DPSL(0); - + /* if want to initialize DMA Tx descriptors */ - if (ENET_DMA_TX == direction){ + if(ENET_DMA_TX == direction) { /* save a copy of the DMA Tx descriptors */ desc_tab = txdesc_tab; buf = &tx_buff[0][0]; count = ENET_TXBUF_NUM; - maxsize = ENET_TXBUF_SIZE; - + maxsize = ENET_TXBUF_SIZE; + /* select ring mode, and enable transmit timestamp function */ desc_status = ENET_TDES0_TTSEN; - + /* configure DMA Tx descriptor table address register */ ENET_DMA_TDTADDR = (uint32_t)desc_tab; dma_current_txdesc = desc_tab; dma_current_ptp_txdesc = desc_ptptab; - }else{ + } else { /* if want to initialize DMA Rx descriptors */ /* save a copy of the DMA Rx descriptors */ desc_tab = rxdesc_tab; buf = &rx_buff[0][0]; count = ENET_RXBUF_NUM; - maxsize = ENET_RXBUF_SIZE; - + maxsize = ENET_RXBUF_SIZE; + /* enable receiving */ desc_status = ENET_RDES0_DAV; /* select receive ring mode and set buffer1 size */ desc_bufsize = (uint32_t)ENET_RXBUF_SIZE; - + /* configure DMA Rx descriptor table address register */ ENET_DMA_RDTADDR = (uint32_t)desc_tab; dma_current_rxdesc = desc_tab; - dma_current_ptp_rxdesc = desc_ptptab; + dma_current_ptp_rxdesc = desc_ptptab; } - - /* configure each descriptor */ - for(num = 0U; num < count; num++){ + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { /* get the pointer to the next descriptor of the descriptor table */ desc = desc_tab + num; /* configure descriptors */ - desc->status = desc_status; + desc->status = desc_status; desc->control_buffer_size = desc_bufsize; desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); - + /* when it is the last descriptor */ - if(num == (count - 1U)){ - if (ENET_DMA_TX == direction){ - /* configure transmit end of ring mode */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ desc->status |= ENET_TDES0_TERM; - }else{ + } else { /* configure receive end of ring mode */ desc->control_buffer_size |= ENET_RDES1_RERM; } @@ -2834,14 +2831,14 @@ void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, ene /* set desc_ptptab equal to desc_tab */ (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; - } - /* when it is the last ptp descriptor, preserve the first descriptor + } + /* when it is the last ptp descriptor, preserve the first descriptor address of desc_ptptab in ptp descriptor status */ - (&desc_ptptab[num-1U])->status = (uint32_t)desc_ptptab; + (&desc_ptptab[num - 1U])->status = (uint32_t)desc_ptptab; } /*! - \brief receive a packet data with timestamp values to application buffer, when the DMA is in normal mode + \brief receive a packet data with timestamp values to application buffer, when the DMA is in normal mode \param[in] bufsize: the size of buffer which is the parameter in function \param[out] buffer: pointer to the application buffer note -- if the input is NULL, user should copy data in application by himself @@ -2851,37 +2848,37 @@ void enet_ptp_normal_descriptors_ring_init(enet_dmadirection_enum direction, ene ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, uint32_t timestamp[]) { uint32_t offset = 0U, size = 0U; - + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { return ERROR; } - + /* if buffer pointer is null, indicates that users has copied data in application */ - if(NULL != buffer){ + if(NULL != buffer) { /* if no error occurs, and the frame uses only one descriptor */ if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && - ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && - ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))){ - + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { + /* get the frame length except CRC */ size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; /* if is a type frame, and CRC is not included in forwarding frame */ - if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))){ + if((RESET != (ENET_MAC_CFG & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { size = size + 4U; } - + /* to avoid situation that the frame size exceeds the buffer length */ - if(size > bufsize){ + if(size > bufsize) { return ERROR; } /* copy data from Rx buffer to application buffer */ - for(offset = 0U; offset < size; offset++){ + for(offset = 0U; offset < size; offset++) { (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_rxdesc->buffer1_addr) + offset)); } - - }else{ + + } else { return ERROR; } } @@ -2891,42 +2888,42 @@ ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, u dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc ->buffer1_addr ; dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc ->buffer2_next_desc_addr; - + /* enable reception, descriptor is owned by DMA */ dma_current_rxdesc->status = ENET_RDES0_DAV; - + /* check Rx buffer unavailable flag status */ - if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){ + if((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)) { /* clear RBU flag */ ENET_DMA_STAT = ENET_DMA_STAT_RBU; /* resume DMA reception by writing to the RPEN register*/ ENET_DMA_RPEN = 0U; } - - /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ /* chained mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){ - dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->buffer2_next_desc_addr); + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->buffer2_next_desc_addr); /* if it is the last ptp descriptor */ - if(0U != dma_current_ptp_rxdesc->status){ + if(0U != dma_current_ptp_rxdesc->status) { /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ - dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); - }else{ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { /* ponter to the next ptp descriptor */ dma_current_ptp_rxdesc++; } - }else{ - /* ring mode */ - if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){ + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR); + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR); /* RDES2 and RDES3 will not be covered by buffer address, so do not need to preserve a new table, use the same table with RxDMA descriptor */ - dma_current_ptp_rxdesc = (enet_descriptors_struct*) (dma_current_ptp_rxdesc->status); - }else{ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); dma_current_ptp_rxdesc ++; } } @@ -2935,7 +2932,7 @@ ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, u } /*! - \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode \param[in] buffer: pointer on the application buffer note -- if the input is NULL, user should copy data in application by himself \param[in] length: the length of frame data to be transmitted @@ -2946,23 +2943,23 @@ ErrStatus enet_ptpframe_receive_normal_mode(uint8_t *buffer, uint32_t bufsize, u ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]) { uint32_t offset = 0U, timeout = 0U; - uint32_t dma_tbu_flag, dma_tu_flag, tdes0_ttmss_flag; - + uint32_t dma_tbu_flag, dma_tu_flag, tdes0_ttmss_flag; + /* the descriptor is busy due to own by the DMA */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { return ERROR; } /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ - if(length > ENET_MAX_FRAME_SIZE){ + if(length > ENET_MAX_FRAME_SIZE) { return ERROR; } - + /* if buffer pointer is null, indicates that users has handled data in application */ - if(NULL != buffer){ + if(NULL != buffer) { /* copy frame data from application buffer to Tx buffer */ - for(offset = 0U; offset < length; offset++){ - (*(__IO uint8_t *) (uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + for(offset = 0U; offset < length; offset++) { + (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); } } /* set the frame length */ @@ -2971,31 +2968,31 @@ ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, u dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; /* enable the DMA transmission */ dma_current_txdesc->status |= ENET_TDES0_DAV; - + /* check Tx buffer unavailable flag status */ - dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); - - if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){ + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { /* clear TBU and TU flag */ ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); /* resume DMA transmission by writing to the TPEN register*/ ENET_DMA_TPEN = 0U; } - + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ - if(NULL != timestamp){ + if(NULL != timestamp) { /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ - do{ + do { tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); timeout++; - }while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); - + } while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { return ERROR; - } - + } + /* clear the ENET_TDES0_TTMSS flag */ dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; /* get the timestamp value of the transmit frame */ @@ -3005,30 +3002,30 @@ ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, u dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc ->buffer1_addr ; dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc ->buffer2_next_desc_addr; - /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */ + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */ /* chained mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ - dma_current_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->buffer2_next_desc_addr); + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->buffer2_next_desc_addr); /* if it is the last ptp descriptor */ - if(0U != dma_current_ptp_txdesc->status){ + if(0U != dma_current_ptp_txdesc->status) { /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ - dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status); - }else{ + dma_current_ptp_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->status); + } else { /* ponter to the next ptp descriptor */ dma_current_ptp_txdesc++; } - }else{ - /* ring mode */ - if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { /* if is the last descriptor in table, the next descriptor is the table header */ - dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR); /* TDES2 and TDES3 will not be covered by buffer address, so do not need to preserve a new table, use the same table with TxDMA descriptor */ - dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status); - }else{ + dma_current_ptp_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->status); + } else { /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ - dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); - dma_current_ptp_txdesc ++; + dma_current_txdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)); + dma_current_ptp_txdesc ++; } } return SUCCESS; @@ -3037,7 +3034,7 @@ ErrStatus enet_ptpframe_transmit_normal_mode(uint8_t *buffer, uint32_t length, u #endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ /*! - \brief wakeup frame filter register pointer reset + \brief wakeup frame filter register pointer reset \param[in] none \param[out] none \retval none @@ -3048,7 +3045,7 @@ void enet_wum_filter_register_pointer_reset(void) } /*! - \brief set the remote wakeup frame registers + \brief set the remote wakeup frame registers \param[in] pdata: pointer to buffer data which is written to remote wakeup frame registers (8 words total) \param[out] none \retval none @@ -3056,15 +3053,15 @@ void enet_wum_filter_register_pointer_reset(void) void enet_wum_filter_config(uint32_t pdata[]) { uint32_t num = 0U; - + /* configure ENET_MAC_RWFF register */ - for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++){ + for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++) { ENET_MAC_RWFF = pdata[num]; } } /*! - \brief enable wakeup management features + \brief enable wakeup management features \param[in] feature: the wake up type which is selected one or more parameters can be selected which are shown as below \arg ENET_WUM_POWER_DOWN: power down mode @@ -3080,7 +3077,7 @@ void enet_wum_feature_enable(uint32_t feature) } /*! - \brief disable wakeup management features + \brief disable wakeup management features \param[in] feature: the wake up type which is selected one or more parameters can be selected which are shown as below \arg ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception @@ -3095,8 +3092,8 @@ void enet_wum_feature_disable(uint32_t feature) } /*! - \brief reset the MAC statistics counters - \param[in] none + \brief reset the MAC statistics counters + \param[in] none \param[out] none \retval none */ @@ -3124,7 +3121,7 @@ void enet_msc_feature_enable(uint32_t feature) /*! \brief disable the MAC statistics counter features \param[in] feature: the feature of MAC statistics counter - one or more parameters can be selected which are shown as below + one or more parameters can be selected which are shown as below \arg ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover \arg ENET_MSC_RESET_ON_READ: reset on read \arg ENET_MSC_COUNTERS_FREEZE: MSC counter freeze @@ -3133,11 +3130,11 @@ void enet_msc_feature_enable(uint32_t feature) */ void enet_msc_feature_disable(uint32_t feature) { - ENET_MSC_CTL &= (~feature); + ENET_MSC_CTL &= (~feature); } /*! - \brief configure MAC statistics counters preset mode + \brief configure MAC statistics counters preset mode \param[in] mode: MSC counters preset mode, refer to enet_msc_preset_enum only one parameter can be selected which is shown as below \arg ENET_MSC_PRESET_NONE: do not preset MSC counter @@ -3153,7 +3150,7 @@ void enet_msc_counters_preset_config(enet_msc_preset_enum mode) } /*! - \brief get MAC statistics counter + \brief get MAC statistics counter \param[in] counter: MSC counters which is selected, refer to enet_msc_counter_enum only one parameter can be selected which is shown as below \arg ENET_MSC_TX_SCCNT: MSC transmitted good frames after a single collision counter @@ -3168,9 +3165,9 @@ void enet_msc_counters_preset_config(enet_msc_preset_enum mode) uint32_t enet_msc_counters_get(enet_msc_counter_enum counter) { uint32_t reval; - + reval = REG32((ENET + (uint32_t)counter)); - + return reval; } @@ -3230,7 +3227,7 @@ void enet_ptp_feature_disable(uint32_t feature) \arg ENET_SNOOPING_PTP_VERSION_2: version 2 \arg ENET_SNOOPING_PTP_VERSION_1: version 1 \arg ENET_EVENT_TYPE_MESSAGES_SNAPSHOT: only event type messages are taken snapshot - \arg ENET_ALL_TYPE_MESSAGES_SNAPSHOT: all type messages are taken snapshot except announce, + \arg ENET_ALL_TYPE_MESSAGES_SNAPSHOT: all type messages are taken snapshot except announce, management and signaling message \arg ENET_MASTER_NODE_MESSAGE_SNAPSHOT: snapshot is only take for master node message \arg ENET_SLAVE_NODE_MESSAGE_SNAPSHOT: snapshot is only taken for slave node message @@ -3243,7 +3240,7 @@ ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func) uint32_t timeout = 0U; ErrStatus enet_state = SUCCESS; - switch(func){ + switch(func) { case ENET_CKNT_ORDINARY: case ENET_CKNT_BOUNDARY: case ENET_CKNT_END_TO_END: @@ -3251,53 +3248,53 @@ ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func) ENET_PTP_TSCTL &= ~ENET_PTP_TSCTL_CKNT; ENET_PTP_TSCTL |= (uint32_t)func; break; - case ENET_PTP_ADDEND_UPDATE: + case ENET_PTP_ADDEND_UPDATE: /* this bit must be read as zero before application set it */ - do{ - temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSARU; + do { + temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSARU; timeout++; - }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { enet_state = ERROR; - }else{ + } else { ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSARU; - } + } break; case ENET_PTP_SYSTIME_UPDATE: /* both the TMSSTU and TMSSTI bits must be read as zero before application set this bit */ - do{ - temp_state = ENET_PTP_TSCTL & (ENET_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); + do { + temp_state = ENET_PTP_TSCTL & (ENET_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); timeout++; - }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { enet_state = ERROR; - }else{ + } else { ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTU; - } - break; + } + break; case ENET_PTP_SYSTIME_INIT: /* this bit must be read as zero before application set it */ - do{ - temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSSTI; + do { + temp_state = ENET_PTP_TSCTL & ENET_PTP_TSCTL_TMSSTI; timeout++; - }while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); /* return ERROR due to timeout */ - if(ENET_DELAY_TO == timeout){ + if(ENET_DELAY_TO == timeout) { enet_state = ERROR; - }else{ + } else { ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTI; - } - break; + } + break; default: - temp_config = (uint32_t)func & (~BIT(31)); - if(RESET != ((uint32_t)func & BIT(31))){ - ENET_PTP_TSCTL |= temp_config; - }else{ - ENET_PTP_TSCTL &= ~temp_config; + temp_config = (uint32_t)func & (~BIT(31)); + if(RESET != ((uint32_t)func & BIT(31))) { + ENET_PTP_TSCTL |= temp_config; + } else { + ENET_PTP_TSCTL &= ~temp_config; } - break; + break; } return enet_state; @@ -3332,7 +3329,7 @@ void enet_ptp_timestamp_addend_config(uint32_t add) \arg ENET_PTP_ADD_TO_TIME: timestamp update value is added to system time \arg ENET_PTP_SUBSTRACT_FROM_TIME: timestamp update value is subtracted from system time \param[in] second: initializing or adding/subtracting to second of the system time - \param[in] subsecond: the current subsecond of the system time + \param[in] subsecond: the current subsecond of the system time with 0.46 ns accuracy if required accuracy is 20 ns \param[out] none \retval none @@ -3340,7 +3337,7 @@ void enet_ptp_timestamp_addend_config(uint32_t add) void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond) { ENET_PTP_TSUH = second; - ENET_PTP_TSUL = sign | PTP_TSUL_TMSUSS(subsecond); + ENET_PTP_TSUL = sign | PTP_TSUL_TMSUSS(subsecond); } /*! @@ -3359,7 +3356,7 @@ void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond) /*! \brief get the current system time \param[in] none - \param[out] systime_struct: pointer to a enet_ptp_systime_struct structure which contains + \param[out] systime_struct: pointer to a enet_ptp_systime_struct structure which contains parameters of PTP system time members of the structure and the member values are shown as below: second: 0x0 - 0xFFFF FFFF @@ -3372,9 +3369,9 @@ void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct) uint32_t temp_sec = 0U, temp_subs = 0U; /* get the value of sysytem time registers */ - temp_sec = (uint32_t)ENET_PTP_TSH; + temp_sec = (uint32_t)ENET_PTP_TSH; temp_subs = (uint32_t)ENET_PTP_TSL; - + /* get sysytem time and construct the enet_ptp_systime_struct structure */ systime_struct->second = temp_sec; systime_struct->subsecond = GET_PTP_TSL_STMSS(temp_subs); @@ -3386,15 +3383,15 @@ void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct) \param[in] freq: PPS output frequency only one parameter can be selected which is shown as below \arg ENET_PPSOFC_1HZ: PPS output 1Hz frequency - \arg ENET_PPSOFC_2HZ: PPS output 2Hz frequency - \arg ENET_PPSOFC_4HZ: PPS output 4Hz frequency - \arg ENET_PPSOFC_8HZ: PPS output 8Hz frequency - \arg ENET_PPSOFC_16HZ: PPS output 16Hz frequency - \arg ENET_PPSOFC_32HZ: PPS output 32Hz frequency + \arg ENET_PPSOFC_2HZ: PPS output 2Hz frequency + \arg ENET_PPSOFC_4HZ: PPS output 4Hz frequency + \arg ENET_PPSOFC_8HZ: PPS output 8Hz frequency + \arg ENET_PPSOFC_16HZ: PPS output 16Hz frequency + \arg ENET_PPSOFC_32HZ: PPS output 32Hz frequency \arg ENET_PPSOFC_64HZ: PPS output 64Hz frequency \arg ENET_PPSOFC_128HZ: PPS output 128Hz frequency \arg ENET_PPSOFC_256HZ: PPS output 256Hz frequency - \arg ENET_PPSOFC_512HZ: PPS output 512Hz frequency + \arg ENET_PPSOFC_512HZ: PPS output 512Hz frequency \arg ENET_PPSOFC_1024HZ: PPS output 1024Hz frequency \arg ENET_PPSOFC_2048HZ: PPS output 2048Hz frequency \arg ENET_PPSOFC_4096HZ: PPS output 4096Hz frequency @@ -3423,7 +3420,7 @@ void enet_initpara_reset(void) enet_initpara.dma_maxburst = 0U; enet_initpara.dma_arbitration = 0U; enet_initpara.store_forward_mode = 0U; - enet_initpara.dma_function = 0U; + enet_initpara.dma_function = 0U; enet_initpara.vlan_config = 0U; enet_initpara.flow_control = 0U; enet_initpara.hashtable_high = 0U; @@ -3432,10 +3429,10 @@ void enet_initpara_reset(void) enet_initpara.halfduplex_param = 0U; enet_initpara.timer_config = 0U; enet_initpara.interframegap = 0U; -} +} /*! - \brief initialize ENET peripheral with generally concerned parameters, call it by enet_init() + \brief initialize ENET peripheral with generally concerned parameters, call it by enet_init() \param[in] none \param[out] none \retval none @@ -3449,20 +3446,20 @@ static void enet_default_init(void) reg_value = ENET_MAC_CFG; reg_value &= MAC_CFG_MASK; reg_value |= ENET_WATCHDOG_ENABLE | ENET_JABBER_ENABLE | ENET_INTERFRAMEGAP_96BIT \ - | ENET_SPEEDMODE_10M |ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \ - | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \ - | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \ - | ENET_DEFERRALCHECK_DISABLE \ - | ENET_TYPEFRAME_CRC_DROP_DISABLE \ - | ENET_AUTO_PADCRC_DROP_DISABLE \ - | ENET_CHECKSUMOFFLOAD_DISABLE; + | ENET_SPEEDMODE_10M | ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \ + | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \ + | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \ + | ENET_DEFERRALCHECK_DISABLE \ + | ENET_TYPEFRAME_CRC_DROP_DISABLE \ + | ENET_AUTO_PADCRC_DROP_DISABLE \ + | ENET_CHECKSUMOFFLOAD_DISABLE; ENET_MAC_CFG = reg_value; - + /* configure ENET_MAC_FRMF register */ - ENET_MAC_FRMF = ENET_SRC_FILTER_DISABLE |ENET_DEST_FILTER_INVERSE_DISABLE \ - |ENET_MULTICAST_FILTER_PERFECT |ENET_UNICAST_FILTER_PERFECT \ - |ENET_PCFRM_PREVENT_ALL |ENET_BROADCASTFRAMES_ENABLE \ - |ENET_PROMISCUOUS_DISABLE |ENET_RX_FILTER_ENABLE; + ENET_MAC_FRMF = ENET_SRC_FILTER_DISABLE | ENET_DEST_FILTER_INVERSE_DISABLE \ + | ENET_MULTICAST_FILTER_PERFECT | ENET_UNICAST_FILTER_PERFECT \ + | ENET_PCFRM_PREVENT_ALL | ENET_BROADCASTFRAMES_ENABLE \ + | ENET_PROMISCUOUS_DISABLE | ENET_RX_FILTER_ENABLE; /* configure ENET_MAC_HLH, ENET_MAC_HLL register */ ENET_MAC_HLH = 0x0U; @@ -3472,31 +3469,31 @@ static void enet_default_init(void) /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */ reg_value = ENET_MAC_FCTL; reg_value &= MAC_FCTL_MASK; - reg_value |= MAC_FCTL_PTM(0) |ENET_ZERO_QUANTA_PAUSE_DISABLE \ - |ENET_PAUSETIME_MINUS4 |ENET_UNIQUE_PAUSEDETECT \ - |ENET_RX_FLOWCONTROL_DISABLE |ENET_TX_FLOWCONTROL_DISABLE; + reg_value |= MAC_FCTL_PTM(0) | ENET_ZERO_QUANTA_PAUSE_DISABLE \ + | ENET_PAUSETIME_MINUS4 | ENET_UNIQUE_PAUSEDETECT \ + | ENET_RX_FLOWCONTROL_DISABLE | ENET_TX_FLOWCONTROL_DISABLE; ENET_MAC_FCTL = reg_value; /* configure ENET_MAC_VLT register */ - ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT |MAC_VLT_VLTI(0); + ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT | MAC_VLT_VLTI(0); /* DMA */ /* configure ENET_DMA_CTL register */ reg_value = ENET_DMA_CTL; reg_value &= DMA_CTL_MASK; - reg_value |= ENET_TCPIP_CKSUMERROR_DROP |ENET_RX_MODE_STOREFORWARD \ - |ENET_FLUSH_RXFRAME_ENABLE |ENET_TX_MODE_STOREFORWARD \ - |ENET_TX_THRESHOLD_64BYTES |ENET_RX_THRESHOLD_64BYTES \ - |ENET_SECONDFRAME_OPT_DISABLE; + reg_value |= ENET_TCPIP_CKSUMERROR_DROP | ENET_RX_MODE_STOREFORWARD \ + | ENET_FLUSH_RXFRAME_ENABLE | ENET_TX_MODE_STOREFORWARD \ + | ENET_TX_THRESHOLD_64BYTES | ENET_RX_THRESHOLD_64BYTES \ + | ENET_SECONDFRAME_OPT_DISABLE; ENET_DMA_CTL = reg_value; /* configure ENET_DMA_BCTL register */ reg_value = ENET_DMA_BCTL; reg_value &= DMA_BCTL_MASK; - reg_value = ENET_ADDRESS_ALIGN_ENABLE |ENET_ARBITRATION_RXTX_2_1 \ - |ENET_RXDP_32BEAT |ENET_PGBL_32BEAT |ENET_RXTX_DIFFERENT_PGBL \ - |ENET_FIXED_BURST_ENABLE |ENET_MIXED_BURST_DISABLE \ - |ENET_NORMAL_DESCRIPTOR; + reg_value = ENET_ADDRESS_ALIGN_ENABLE | ENET_ARBITRATION_RXTX_2_1 \ + | ENET_RXDP_32BEAT | ENET_PGBL_32BEAT | ENET_RXTX_DIFFERENT_PGBL \ + | ENET_FIXED_BURST_ENABLE | ENET_MIXED_BURST_DISABLE \ + | ENET_NORMAL_DESCRIPTOR; ENET_DMA_BCTL = reg_value; } @@ -3509,9 +3506,9 @@ static void enet_default_init(void) */ static void enet_delay(uint32_t ncount) { - __IO uint32_t delay_time = 0U; - - for(delay_time = ncount; delay_time != 0U; delay_time--){ + __IO uint32_t delay_time = 0U; + + for(delay_time = ncount; delay_time != 0U; delay_time--) { } } #endif /* USE_DELAY */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c index 11def48..ae15aca 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_exmc.c \brief EXMC driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -112,9 +110,6 @@ OF SUCH DAMAGE. #define SDARI_ARINTV_OFFSET ((uint32_t)1U) -#define SDRSCTL_SSCR_OFFSET ((uint32_t)1U) -#define SDRSCTL_SDSC_OFFSET ((uint32_t)4U) - #define SDSTAT_STA0_OFFSET ((uint32_t)1U) #define SDSTAT_STA1_OFFSET ((uint32_t)3U) @@ -124,7 +119,7 @@ OF SUCH DAMAGE. #define INTEN_INTS_OFFSET ((uint32_t)3U) /*! - \brief deinitialize EXMC NOR/SRAM region + \brief deinitialize EXMC NOR/SRAM region \param[in] exmc_norsram_region: select the region of bank0 only one parameter can be selected which is shown as below: \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) @@ -140,12 +135,12 @@ void exmc_norsram_deinit(uint32_t exmc_norsram_region) } /*! - \brief initialize exmc_norsram_parameter_struct with the default values + \brief initialize exmc_norsram_parameter_struct with the default values \param[in] none \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer \retval none */ -void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct) { /* configure the structure with default values */ exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0; @@ -171,7 +166,7 @@ void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_i exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK; exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A; - /* write timing configure, when extended mode is used */ + /* configure write timing, when extended mode is used */ exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU; exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU; exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU; @@ -180,11 +175,11 @@ void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_i } /*! - \brief initialize EXMC NOR/SRAM region + \brief initialize EXMC NOR/SRAM region \param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter norsram_region: EXMC_BANK0_NORSRAM_REGIONx, x=0..3 write_mode: EXMC_ASYN_WRITE, EXMC_SYN_WRITE - extended_mode: ENABLE or DISABLE + extended_mode: ENABLE or DISABLE asyn_wait: ENABLE or DISABLE nwait_signal: ENABLE or DISABLE memory_write: ENABLE or DISABLE @@ -199,7 +194,7 @@ void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_i asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D syn_data_latency: EXMC_DATALAT_x_CLK, x=2..17 syn_clk_division: EXMC_SYN_CLOCK_RATIO_DISABLE, EXMC_SYN_CLOCK_RATIO_x_CLK, x=2..16 - bus_latency: 0x0U~0xFU + bus_latency: 0x0U~0xFU asyn_data_setuptime: 0x01U~0xFFU asyn_address_holdtime: 0x1U~0xFU asyn_address_setuptime: 0x0U~0xFU @@ -207,60 +202,62 @@ void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_i asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D syn_data_latency: EXMC_DATALAT_x_CLK, x=2..17 syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2..16 - bus_latency: 0x0U~0xFU + bus_latency: 0x0U~0xFU asyn_data_setuptime: 0x01U~0xFFU asyn_address_holdtime: 0x1U~0xFU asyn_address_setuptime: 0x0U~0xFU \param[out] none \retval none */ -void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) +void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct) { - uint32_t snctl = 0x00000000U,sntcfg = 0x00000000U,snwtcfg = 0x00000000U; + uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U, snwtcfg = 0x00000000U; /* get the register value */ snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region); /* clear relative bits */ - snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | - EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WREN | - EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_SYNCWR | - EXMC_SNCTL_NRMUX )); + snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | + EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WEN | + EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWTEN | EXMC_SNCTL_SYNCWR | + EXMC_SNCTL_NRMUX)); + /* configure control bits */ snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | - exmc_norsram_init_struct->memory_type | - exmc_norsram_init_struct->databus_width | - (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) | - exmc_norsram_init_struct->nwait_polarity | - (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) | - exmc_norsram_init_struct->nwait_config | - (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | - (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | - (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) | - (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) | - exmc_norsram_init_struct->write_mode; - + exmc_norsram_init_struct->memory_type | + exmc_norsram_init_struct->databus_width | + (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) | + exmc_norsram_init_struct->nwait_polarity | + (exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) | + exmc_norsram_init_struct->nwait_config | + (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | + (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | + (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) | + (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) | + exmc_norsram_init_struct->write_mode; + + /* configure timing */ sntcfg = (uint32_t)exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime | - (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | - (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | - (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | - exmc_norsram_init_struct->read_write_timing->syn_clk_division | - exmc_norsram_init_struct->read_write_timing->syn_data_latency | - exmc_norsram_init_struct->read_write_timing->asyn_access_mode; - - /* nor flash access enable */ - if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){ + (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->read_write_timing->syn_clk_division | + exmc_norsram_init_struct->read_write_timing->syn_data_latency | + exmc_norsram_init_struct->read_write_timing->asyn_access_mode; + + /* enable nor flash access */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) { snctl |= (uint32_t)EXMC_SNCTL_NREN; } - /* extended mode configure */ - if(ENABLE == exmc_norsram_init_struct->extended_mode){ + /* configure extended mode */ + if(ENABLE == exmc_norsram_init_struct->extended_mode) { snwtcfg = (uint32_t)exmc_norsram_init_struct->write_timing->asyn_address_setuptime | - (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET )| - (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | - (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | - exmc_norsram_init_struct->write_timing->asyn_access_mode; - }else{ + (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | + (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->write_timing->asyn_access_mode; + } else { snwtcfg = BANK0_SNWTCFG_RESET; } @@ -271,8 +268,8 @@ void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct) } /*! - \brief enable EXMC NOR/PSRAM bank region - \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM bank + \brief enable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specify the region of NOR/PSRAM bank only one parameter can be selected which is shown as below: \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) \param[out] none @@ -284,8 +281,8 @@ void exmc_norsram_enable(uint32_t exmc_norsram_region) } /*! - \brief disable EXMC NOR/PSRAM bank region - \param[in] exmc_norsram_region: specifie the region of NOR/PSRAM Bank + \brief disable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specify the region of NOR/PSRAM Bank only one parameter can be selected which is shown as below: \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) \param[out] none @@ -297,7 +294,7 @@ void exmc_norsram_disable(uint32_t exmc_norsram_region) } /*! - \brief deinitialize EXMC NAND bank + \brief deinitialize EXMC NAND bank \param[in] exmc_nand_bank: select the bank of NAND only one parameter can be selected which is shown as below: \arg EXMC_BANKx_NAND(x=1..2) @@ -314,12 +311,12 @@ void exmc_nand_deinit(uint32_t exmc_nand_bank) } /*! - \brief initialize exmc_norsram_parameter_struct with the default values + \brief initialize exmc_norsram_parameter_struct with the default values \param[in] none \param[out] the initialized struct exmc_norsram_parameter_struct pointer \retval none */ -void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struct) +void exmc_nand_struct_para_init(exmc_nand_parameter_struct *exmc_nand_init_struct) { /* configure the structure with default values */ exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND; @@ -340,7 +337,7 @@ void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struc } /*! - \brief initialize EXMC NAND bank + \brief initialize EXMC NAND bank \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096 @@ -362,37 +359,37 @@ void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struc \param[out] none \retval none */ -void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct) +void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct) { uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U; - - npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)| - EXMC_NPCTL_NDTP | - exmc_nand_init_struct->databus_width | - (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)| - exmc_nand_init_struct->ecc_size | - exmc_nand_init_struct->ctr_latency | - exmc_nand_init_struct->atr_latency; - - npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) | - (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) | - ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) | - (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ ); - - npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) | - (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) | - ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) | - ((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ ); - - /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */ + + npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) | + EXMC_NPCTL_NDTP | + exmc_nand_init_struct->databus_width | + (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET) | + exmc_nand_init_struct->ecc_size | + exmc_nand_init_struct->ctr_latency | + exmc_nand_init_struct->atr_latency; + + npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) | + (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) | + ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) | + (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ); + + npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) | + (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) | + ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) | + ((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ); + + /* initialize EXMC_BANK1_NAND or EXMC_BANK2_NAND */ EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl; EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg; EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg; } /*! - \brief enable NAND bank - \param[in] exmc_nand_bank: specifie the NAND bank + \brief enable NAND bank + \param[in] exmc_nand_bank: specify the NAND bank only one parameter can be selected which is shown as below: \arg EXMC_BANKx_NAND(x=1,2) \param[out] none @@ -404,8 +401,8 @@ void exmc_nand_enable(uint32_t exmc_nand_bank) } /*! - \brief disable NAND bank - \param[in] exmc_nand_bank: specifie the NAND bank + \brief disable NAND bank + \param[in] exmc_nand_bank: specify the NAND bank only one parameter can be selected which is shown as below: \arg EXMC_BANKx_NAND(x=1,2) \param[out] none @@ -417,7 +414,7 @@ void exmc_nand_disable(uint32_t exmc_nand_bank) } /*! - \brief deinitialize EXMC PC card bank + \brief deinitialize EXMC PC card bank \param[in] none \param[out] none \retval none @@ -433,12 +430,12 @@ void exmc_pccard_deinit(void) } /*! - \brief initialize exmc_pccard_parameter_struct with the default values + \brief initialize exmc_pccard_parameter_struct with the default values \param[in] none \param[out] the initialized struct exmc_pccard_parameter_struct pointer \retval none */ -void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct) +void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct) { /* configure the structure with default values */ exmc_pccard_init_struct->wait_feature = DISABLE; @@ -459,7 +456,7 @@ void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init } /*! - \brief initialize EXMC PC card bank + \brief initialize EXMC PC card bank \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16 ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16 @@ -482,35 +479,35 @@ void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init \param[out] none \retval none */ -void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct) +void exmc_pccard_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct) { /* configure the EXMC bank3 PC card control register */ EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) | - EXMC_NAND_DATABUS_WIDTH_16B | - exmc_pccard_init_struct->ctr_latency | - exmc_pccard_init_struct->atr_latency ; - + EXMC_NAND_DATABUS_WIDTH_16B | + exmc_pccard_init_struct->ctr_latency | + exmc_pccard_init_struct->atr_latency ; + /* configure the EXMC bank3 PC card common space timing configuration register */ - EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) | - (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) | - ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) | - (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ ); + EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) | + (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) | + ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) | + (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ); /* configure the EXMC bank3 PC card attribute space timing configuration register */ - EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) | - (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) | - ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) | - ((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ); + EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) | + (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) | + ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) | + ((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ); /* configure the EXMC bank3 PC card io space timing configuration register */ - EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET ) | - (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT ) | - ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD ) | - ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ ); + EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET) | + (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT) | + ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD) | + ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ); } /*! - \brief enable PC Card Bank + \brief enable PC Card Bank \param[in] none \param[out] none \retval none @@ -521,18 +518,18 @@ void exmc_pccard_enable(void) } /*! - \brief disable PC Card Bank + \brief disable PC Card Bank \param[in] none \param[out] none \retval none */ void exmc_pccard_disable(void) { - EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN; + EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN; } /*! - \brief deinitialize EXMC SDRAM device + \brief deinitialize EXMC SDRAM device \param[in] exmc_sdram_device: select the SRAM device only one parameter can be selected which is shown as below: \arg EXMC_SDRAM_DEVICEx(x=0, 1) @@ -551,12 +548,12 @@ void exmc_sdram_deinit(uint32_t exmc_sdram_device) } /*! - \brief initialize exmc_sdram_parameter_struct with the default values + \brief initialize exmc_sdram_parameter_struct with the default values \param[in] none \param[out] the initialized struct exmc_pccard_parameter_struct pointer \retval none */ -void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct) +void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct) { /* configure the structure with default values */ exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0; @@ -567,7 +564,7 @@ void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct* exmc_sdram_init_st exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK; exmc_sdram_init_struct->write_protection = ENABLE; exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE; - exmc_sdram_init_struct->brust_read_switch = DISABLE; + exmc_sdram_init_struct->burst_read_switch = DISABLE; exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_HCLK; exmc_sdram_init_struct->timing->load_mode_register_delay = 16U; @@ -580,11 +577,11 @@ void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct* exmc_sdram_init_st } /*! - \brief initialize EXMC SDRAM device + \brief initialize EXMC SDRAM device \param[in] exmc_sdram_parameter_struct: configure the EXMC SDRAM parameter sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1 pipeline_read_delay: EXMC_PIPELINE_DELAY_x_HCLK,x=0..2 - brust_read_switch: ENABLE or DISABLE + burst_read_switch: ENABLE or DISABLE sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_HCLK,EXMC_SDCLK_PERIODS_3_HCLK write_protection: ENABLE or DISABLE cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1..3 @@ -603,62 +600,62 @@ void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct* exmc_sdram_init_st \param[out] none \retval none */ -void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct) +void exmc_sdram_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct) { uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1; - /* configuration EXMC_SDCTL0 or EXMC_SDCTL1 */ - if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device){ - /* configuration EXMC_SDCTL0 */ - EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = (uint32_t)exmc_sdram_init_struct->column_address_width | - exmc_sdram_init_struct->row_address_width | - exmc_sdram_init_struct->data_width | - exmc_sdram_init_struct->internal_bank_number | - exmc_sdram_init_struct->cas_latency | - (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET)| - exmc_sdram_init_struct->sdclock_config | - (exmc_sdram_init_struct->brust_read_switch << SDCTL_BRSTRD_OFFSET)| - exmc_sdram_init_struct->pipeline_read_delay; + /* configure EXMC_SDCTL0 or EXMC_SDCTL1 */ + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device) { + /* configure EXMC_SDCTL0 */ + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = (uint32_t)(exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET) | + exmc_sdram_init_struct->sdclock_config | + (exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) | + exmc_sdram_init_struct->pipeline_read_delay); - /* configuration EXMC_SDTCFG0 */ - EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) | - (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) | - (((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) | - (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET); - }else{ - /* configuration EXMC_SDCTL0 and EXMC_SDCTL1 */ + /* configure EXMC_SDTCFG0 */ + EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET); + } else { + /* configure EXMC_SDCTL0 and EXMC_SDCTL1 */ /* some bits in the EXMC_SDCTL1 register are reserved */ - sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~( EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK )); - - sdctl0 |= (uint32_t)exmc_sdram_init_struct->sdclock_config | - exmc_sdram_init_struct->brust_read_switch | - exmc_sdram_init_struct->pipeline_read_delay; + sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK)); + + sdctl0 |= (uint32_t)(exmc_sdram_init_struct->sdclock_config | + (exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) | + exmc_sdram_init_struct->pipeline_read_delay); - sdctl1 = (uint32_t)exmc_sdram_init_struct->column_address_width | - exmc_sdram_init_struct->row_address_width | - exmc_sdram_init_struct->data_width | - exmc_sdram_init_struct->internal_bank_number | - exmc_sdram_init_struct->cas_latency | - exmc_sdram_init_struct->write_protection ; + sdctl1 = (uint32_t)(exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET)); EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0; EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1; - - /* configuration EXMC_SDTCFG0 and EXMC_SDTCFG1 */ + + /* configure EXMC_SDTCFG0 and EXMC_SDTCFG1 */ /* some bits in the EXMC_SDTCFG1 register are reserved */ sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD)); - sdtcfg0 |= (uint32_t)(((exmc_sdram_init_struct->timing->auto_refresh_delay)-1U) << SDTCFG_ARFD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_precharge_delay)-1U) << SDTCFG_RPD_OFFSET) | - (((exmc_sdram_init_struct->timing->write_recovery_delay)-1U) << SDTCFG_WRD_OFFSET); + sdtcfg0 |= (uint32_t)((((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET)); - sdtcfg1 = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay)-1U) | - (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay)-1U) << SDTCFG_XSRD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_address_select_delay)-1U) << SDTCFG_RASD_OFFSET) | - (((exmc_sdram_init_struct->timing->row_to_column_delay)-1U) << SDTCFG_RCD_OFFSET); + sdtcfg1 = (uint32_t)(((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET)); EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0; EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1; @@ -666,7 +663,22 @@ void exmc_sdram_init(exmc_sdram_parameter_struct* exmc_sdram_init_struct) } /*! - \brief deinitialize exmc SQPIPSRAM + \brief initialize exmc_sdram_struct_command_para_init with the default values + \param[in] none + \param[out] the initialized struct exmc_sdram_struct_command_para_init pointer + \retval none +*/ +void exmc_sdram_struct_command_para_init(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct) +{ + /* configure the structure with default value */ + exmc_sdram_command_init_struct->mode_register_content = 0U; + exmc_sdram_command_init_struct->auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + exmc_sdram_command_init_struct->bank_select = EXMC_SDRAM_DEVICE0_SELECT; + exmc_sdram_command_init_struct->command = EXMC_SDRAM_NORMAL_OPERATION; +} + +/*! + \brief deinitialize exmc SQPIPSRAM \param[in] none \param[out] none \retval none @@ -682,12 +694,12 @@ void exmc_sqpipsram_deinit(void) } /*! - \brief initialize exmc_sqpipsram_parameter_struct with the default values + \brief initialize exmc_sqpipsram_parameter_struct with the default values \param[in] the struct exmc_sqpipsram_parameter_struct pointer \param[out] none \retval none */ -void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct) +void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct) { /* configure the structure with default values */ exmc_sqpipsram_init_struct->sample_polarity = EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE; @@ -697,7 +709,7 @@ void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct* exmc_sqpip } /*! - \brief initialize EXMC SQPIPSRAM + \brief initialize EXMC SQPIPSRAM \param[in] exmc_sqpipsram_parameter_struct: configure the EXMC SQPIPSRAM parameter sample_polarity: EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE,EXMC_SQPIPSRAM_SAMPLE_FALLING_EDGE id_length: EXMC_SQPIPSRAM_ID_LENGTH_xB,x=8,16,32,64 @@ -706,18 +718,18 @@ void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct* exmc_sqpip \param[out] none \retval none */ -void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct) +void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct) { /* initialize SQPI controller */ EXMC_SINIT = (uint32_t)exmc_sqpipsram_init_struct->sample_polarity | - exmc_sqpipsram_init_struct->id_length | - exmc_sqpipsram_init_struct->address_bits | - exmc_sqpipsram_init_struct->command_bits; + exmc_sqpipsram_init_struct->id_length | + exmc_sqpipsram_init_struct->address_bits | + exmc_sqpipsram_init_struct->command_bits; } /*! - \brief configure consecutive clock - \param[in] clock_mode: specifie when the clock is generated + \brief configure consecutive clock + \param[in] clock_mode: specify when the clock is generated only one parameter can be selected which is shown as below: \arg EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access \arg EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally @@ -726,15 +738,15 @@ void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_st */ void exmc_norsram_consecutive_clock_config(uint32_t clock_mode) { - if (EXMC_CLOCK_UNCONDITIONALLY == clock_mode){ + if(EXMC_CLOCK_UNCONDITIONALLY == clock_mode) { EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY; - }else{ + } else { EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY; } } /*! - \brief configure CRAM page size + \brief configure CRAM page size \param[in] exmc_norsram_region: select the region of bank0 only one parameter can be selected which is shown as below: \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) @@ -758,8 +770,8 @@ void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_s } /*! - \brief enable or disable the EXMC NAND ECC function - \param[in] exmc_nand_bank: specifie the NAND bank + \brief enable or disable the EXMC NAND ECC function + \param[in] exmc_nand_bank: specify the NAND bank only one parameter can be selected which is shown as below: \arg EXMC_BANKx_NAND(x=1,2) \param[in] newvalue: ENABLE or DISABLE @@ -768,18 +780,18 @@ void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_s */ void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue) { - if (ENABLE == newvalue){ + if(ENABLE == newvalue) { /* enable the selected NAND bank ECC function */ EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN; - }else{ + } else { /* disable the selected NAND bank ECC function */ EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_ECCEN; } } /*! - \brief get the EXMC ECC value - \param[in] exmc_nand_bank: specifie the NAND bank + \brief get the EXMC ECC value + \param[in] exmc_nand_bank: specify the NAND bank only one parameter can be selected which is shown as below: \arg EXMC_BANKx_NAND(x=1,2) \param[out] none @@ -791,22 +803,22 @@ uint32_t exmc_ecc_get(uint32_t exmc_nand_bank) } /*! - \brief enable or disable read sample + \brief enable or disable read sample \param[in] newvalue: ENABLE or DISABLE \param[out] none \retval none */ void exmc_sdram_readsample_enable(ControlStatus newvalue) { - if (ENABLE == newvalue){ + if(ENABLE == newvalue) { EXMC_SDRSCTL |= EXMC_SDRSCTL_RSEN; - }else{ + } else { EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN); } } /*! - \brief configure the delayed sample clock of read data + \brief configure the delayed sample clock of read data \param[in] delay_cell: SDRAM the delayed sample clock of read data only one parameter can be selected which is shown as below: \arg EXMC_SDRAM_x_DELAY_CELL(x=0..15) @@ -819,38 +831,37 @@ void exmc_sdram_readsample_enable(ControlStatus newvalue) void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk) { uint32_t sdrsctl = 0U; - + /* reset the bits */ sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR)); /* set the bits */ - sdrsctl |= (uint32_t)(delay_cell & EXMC_SDRSCTL_SDSC) | - ((extra_hclk << SDRSCTL_SSCR_OFFSET) & EXMC_SDRSCTL_SSCR); + sdrsctl |= (uint32_t)(delay_cell | extra_hclk); EXMC_SDRSCTL = sdrsctl; } /*! - \brief configure the SDRAM memory command - \param[in] exmc_sdram_command_init_struct: initialize EXMC SDRAM command + \brief configure the SDRAM memory command + \param[in] exmc_sdram_command_init_struct: initialize EXMC SDRAM command mode_register_content: auto_refresh_number: EXMC_SDRAM_AUTO_REFLESH_x_SDCLK, x=1..15 - bank_select: EXMC_SDRAM_DEVICE0_SELECT, EXMC_SDRAM_DEVICE1_SELECT, EXMC_SDRAM_DEVICE0_1_SELECT - command: EXMC_SDRAM_NORMAL_OPERATION, EXMC_SDRAM_CLOCK_ENABLE, EXMC_SDRAM_PRECHARGE_ALL, - EXMC_SDRAM_AUTO_REFRESH, EXMC_SDRAM_LOAD_MODE_REGISTER, EXMC_SDRAM_SELF_REFRESH, - EXMC_SDRAM_POWERDOWN_ENTRY + bank_select: EXMC_SDRAM_DEVICE0_SELECT, EXMC_SDRAM_DEVICE1_SELECT, EXMC_SDRAM_DEVICE0_1_SELECT + command: EXMC_SDRAM_NORMAL_OPERATION, EXMC_SDRAM_CLOCK_ENABLE, EXMC_SDRAM_PRECHARGE_ALL, + EXMC_SDRAM_AUTO_REFRESH, EXMC_SDRAM_LOAD_MODE_REGISTER, EXMC_SDRAM_SELF_REFRESH, + EXMC_SDRAM_POWERDOWN_ENTRY \param[out] none \retval none */ -void exmc_sdram_command_config(exmc_sdram_command_parameter_struct* exmc_sdram_command_init_struct) +void exmc_sdram_command_config(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct) { /* configure command register */ EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) | - (exmc_sdram_command_init_struct->bank_select) | - ((exmc_sdram_command_init_struct->auto_refresh_number)) | - ((exmc_sdram_command_init_struct->mode_register_content)<bank_select) | + ((exmc_sdram_command_init_struct->auto_refresh_number)) | + ((exmc_sdram_command_init_struct->mode_register_content) << SDCMD_MRC_OFFSET)); } /*! - \brief set auto-refresh interval + \brief set auto-refresh interval \param[in] exmc_count: the number SDRAM clock cycles unit between two successive auto-refresh commands, 0x0000~0x1FFF \param[out] none \retval none @@ -863,7 +874,7 @@ void exmc_sdram_refresh_count_set(uint32_t exmc_count) } /*! - \brief set the number of successive auto-refresh command + \brief set the number of successive auto-refresh command \param[in] exmc_number: the number of successive Auto-refresh cycles will be send, 1~15 \param[out] none \retval none @@ -876,8 +887,8 @@ void exmc_sdram_autorefresh_number_set(uint32_t exmc_number) } /*! - \brief config the write protection function - \param[in] exmc_sdram_device: specifie the SDRAM device + \brief configure the write protection function + \param[in] exmc_sdram_device: specify the SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_SDRAM_DEVICEx(x=0,1) \param[in] newvalue: ENABLE or DISABLE @@ -886,17 +897,17 @@ void exmc_sdram_autorefresh_number_set(uint32_t exmc_number) */ void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue) { - if (ENABLE == newvalue){ + if(ENABLE == newvalue) { EXMC_SDCTL(exmc_sdram_device) |= (uint32_t)EXMC_SDCTL_WPEN; - }else{ + } else { EXMC_SDCTL(exmc_sdram_device) &= ~((uint32_t)EXMC_SDCTL_WPEN); } } /*! - \brief get the status of SDRAM device0 or device1 - \param[in] exmc_sdram_device: specifie the SDRAM device + \brief get the status of SDRAM device0 or device1 + \param[in] exmc_sdram_device: specify the SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_SDRAM_DEVICEx(x=0,1) \param[out] none @@ -906,9 +917,9 @@ uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device) { uint32_t sdstat = 0U; - if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device){ + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device) { sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA0) >> SDSTAT_STA0_OFFSET); - }else{ + } else { sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET); } @@ -916,7 +927,7 @@ uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device) } /*! - \brief set the read command + \brief set the read command \param[in] read_command_mode: configure SPI PSRAM read command mode only one parameter can be selected which is shown as below: \arg EXMC_SQPIPSRAM_READ_MODE_DISABLE: not SPI mode @@ -928,18 +939,18 @@ uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device) \param[out] none \retval none */ -void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle, uint32_t read_command_code) +void exmc_sqpipsram_read_command_set(uint32_t read_command_mode, uint32_t read_wait_cycle, uint32_t read_command_code) { uint32_t srcmd; - + srcmd = (uint32_t) read_command_mode | - ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) | - ((read_command_code & EXMC_SRCMD_RCMD)); + ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) | + ((read_command_code & EXMC_SRCMD_RCMD)); EXMC_SRCMD = srcmd; } /*! - \brief set the write command + \brief set the write command \param[in] write_command_mode: configure SPI PSRAM write command mode only one parameter can be selected which is shown as below: \arg EXMC_SQPIPSRAM_WRITE_MODE_DISABLE: not SPI mode @@ -951,18 +962,18 @@ void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wa \param[out] none \retval none */ -void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle, uint32_t write_command_code) +void exmc_sqpipsram_write_command_set(uint32_t write_command_mode, uint32_t write_wait_cycle, uint32_t write_command_code) { uint32_t swcmd; - + swcmd = (uint32_t) write_command_mode | - ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) | - ((write_command_code & EXMC_SWCMD_WCMD)); + ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) | + ((write_command_code & EXMC_SWCMD_WCMD)); EXMC_SWCMD = swcmd; } /*! - \brief send SPI read ID command + \brief send SPI read ID command \param[in] none \param[out] none \retval none @@ -973,7 +984,7 @@ void exmc_sqpipsram_read_id_command_send(void) } /*! - \brief send SPI special command which does not have address and data phase + \brief send SPI special command which does not have address and data phase \param[in] none \param[out] none \retval none @@ -984,7 +995,7 @@ void exmc_sqpipsram_write_cmd_send(void) } /*! - \brief get the EXMC SPI ID low data + \brief get the EXMC SPI ID low data \param[in] none \param[out] none \retval the ID low data @@ -995,7 +1006,7 @@ uint32_t exmc_sqpipsram_low_id_get(void) } /*! - \brief get the EXMC SPI ID high data + \brief get the EXMC SPI ID high data \param[in] none \param[out] none \retval the ID high data @@ -1006,7 +1017,7 @@ uint32_t exmc_sqpipsram_high_id_get(void) } /*! - \brief get the bit value of EXMC send write command bit or read ID command + \brief get the bit value of EXMC send write command bit or read ID command \param[in] send_command_flag: the send command flag only one parameter can be selected which is shown as below: \arg EXMC_SEND_COMMAND_FLAG_RDID: EXMC_SRCMD_RDID flag bit @@ -1017,33 +1028,33 @@ uint32_t exmc_sqpipsram_high_id_get(void) FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag) { uint32_t flag = 0x00000000U; - - if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag){ + + if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag) { flag = EXMC_SRCMD; - }else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag){ + } else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag) { flag = EXMC_SWCMD; - }else{ + } else { } - - if (flag & send_command_flag){ + + if(flag & send_command_flag) { /* flag is set */ return SET; - }else{ + } else { /* flag is reset */ return RESET; } } /*! - \brief enable EXMC interrupt - \param[in] exmc_bank: specifies the NAND bank,PC card bank or SDRAM device + \brief enable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank,PC card bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 \arg EXMC_BANK3_PCCARD: the PC card bank \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 - \param[in] interrupt: specify get which interrupt flag + \param[in] interrupt: specify EXMC interrupt flag only one parameter can be selected which is shown as below: \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag @@ -1054,25 +1065,25 @@ FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag) */ void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt) { - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ EXMC_NPINTEN(exmc_bank) |= interrupt; - }else{ + } else { /* SDRAM device0 or device1 */ EXMC_SDARI |= EXMC_SDARI_REIE; } } /*! - \brief disable EXMC interrupt - \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \brief disable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 \arg EXMC_BANK3_PCCARD: the PC card bank \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 - \param[in] interrupt: specify get which interrupt flag + \param[in] interrupt: specify EXMC interrupt flag only one parameter can be selected which is shown as below: \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag @@ -1083,18 +1094,18 @@ void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt) */ void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt) { - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ EXMC_NPINTEN(exmc_bank) &= ~interrupt; - }else{ + } else { /* SDRAM device0 or device1 */ EXMC_SDARI &= ~EXMC_SDARI_REIE; } } /*! - \brief get EXMC flag status - \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \brief get EXMC flag status + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 @@ -1112,30 +1123,30 @@ void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt) \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag) +FlagStatus exmc_flag_get(uint32_t exmc_bank, uint32_t flag) { uint32_t status = 0x00000000U; - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ status = EXMC_NPINTEN(exmc_bank); - }else{ - /* SDRAM device0 or device1 */ + } else { + /* SDRAM device0 or device1 */ status = EXMC_SDSTAT; } - - if ((status & flag) != (uint32_t)flag ){ + + if((status & flag) != (uint32_t)flag) { /* flag is reset */ return RESET; - }else{ + } else { /* flag is set */ return SET; } } /*! - \brief clear EXMC flag status - \param[in] exmc_bank: specifie the NAND bank , PCCARD bank or SDRAM device + \brief clear EXMC flag status + \param[in] exmc_bank: specify the NAND bank , PCCARD bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 @@ -1155,18 +1166,18 @@ FlagStatus exmc_flag_get(uint32_t exmc_bank,uint32_t flag) */ void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag) { - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ EXMC_NPINTEN(exmc_bank) &= ~flag; - }else{ + } else { /* SDRAM device0 or device1 */ EXMC_SDSTAT &= ~flag; - } + } } /*! - \brief get EXMC interrupt flag - \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \brief get EXMC interrupt flag + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 @@ -1184,32 +1195,32 @@ void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag) */ FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt) { - uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U; + uint32_t status = 0x00000000U, interrupt_enable = 0x00000000U, interrupt_state = 0x00000000U; - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ status = EXMC_NPINTEN(exmc_bank); interrupt_state = (status & (interrupt >> INTEN_INTS_OFFSET)); - }else{ - /* SDRAM device0 or device1 */ + } else { + /* SDRAM device0 or device1 */ status = EXMC_SDARI; interrupt_state = (EXMC_SDSTAT & EXMC_SDSDAT_REIF); } interrupt_enable = (status & interrupt); - if ((interrupt_enable) && (interrupt_state)){ + if((interrupt_enable) && (interrupt_state)) { /* interrupt flag is set */ return SET; - }else{ + } else { /* interrupt flag is reset */ return RESET; } } /*! - \brief clear EXMC interrupt flag - \param[in] exmc_bank: specifies the NAND bank , PC card bank or SDRAM device + \brief clear EXMC interrupt flag + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device only one parameter can be selected which is shown as below: \arg EXMC_BANK1_NAND: the NAND bank1 \arg EXMC_BANK2_NAND: the NAND bank2 @@ -1227,10 +1238,10 @@ FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt) */ void exmc_interrupt_flag_clear(uint32_t exmc_bank, uint32_t interrupt) { - if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)){ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { /* NAND bank1,bank2 or PC card bank3 */ EXMC_NPINTEN(exmc_bank) &= ~(interrupt >> INTEN_INTS_OFFSET); - }else{ + } else { /* SDRAM device0 or device1 */ EXMC_SDARI |= EXMC_SDARI_REC; } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c index a37e7cd..3be3003 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c @@ -1,41 +1,40 @@ /*! \file gd32f4xx_exti.c \brief EXTI driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.1, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_exti.h" +#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U) + /*! \brief deinitialize the EXTI \param[in] none @@ -45,15 +44,15 @@ OF SUCH DAMAGE. void exti_deinit(void) { /* reset the value of all the EXTI registers */ - EXTI_INTEN = (uint32_t)0x00000000U; - EXTI_EVEN = (uint32_t)0x00000000U; - EXTI_RTEN = (uint32_t)0x00000000U; - EXTI_FTEN = (uint32_t)0x00000000U; - EXTI_SWIEV = (uint32_t)0x00000000U; + EXTI_INTEN = EXTI_REG_RESET_VALUE; + EXTI_EVEN = EXTI_REG_RESET_VALUE; + EXTI_RTEN = EXTI_REG_RESET_VALUE; + EXTI_FTEN = EXTI_REG_RESET_VALUE; + EXTI_SWIEV = EXTI_REG_RESET_VALUE; } /*! - \brief initialize the EXTI + \brief initialize the EXTI line x \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -71,17 +70,17 @@ void exti_deinit(void) \retval none */ void exti_init(exti_line_enum linex, \ - exti_mode_enum mode, \ - exti_trig_type_enum trig_type) + exti_mode_enum mode, \ + exti_trig_type_enum trig_type) { /* reset the EXTI line x */ EXTI_INTEN &= ~(uint32_t)linex; EXTI_EVEN &= ~(uint32_t)linex; EXTI_RTEN &= ~(uint32_t)linex; EXTI_FTEN &= ~(uint32_t)linex; - + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ - switch(mode){ + switch(mode) { case EXTI_INTERRUPT: EXTI_INTEN |= (uint32_t)linex; break; @@ -91,9 +90,9 @@ void exti_init(exti_line_enum linex, \ default: break; } - + /* set the EXTI trigger type */ - switch(trig_type){ + switch(trig_type) { case EXTI_TRIG_RISING: EXTI_RTEN |= (uint32_t)linex; EXTI_FTEN &= ~(uint32_t)linex; @@ -165,7 +164,7 @@ void exti_event_disable(exti_line_enum linex) } /*! - \brief enable EXTI software interrupt event + \brief enable the software interrupt event from EXTI line x \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -178,7 +177,7 @@ void exti_software_interrupt_enable(exti_line_enum linex) } /*! - \brief disable EXTI software interrupt event + \brief disable the software interrupt event from EXTI line x \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -191,7 +190,7 @@ void exti_software_interrupt_disable(exti_line_enum linex) } /*! - \brief get EXTI lines flag + \brief get EXTI line x interrupt pending flag \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -200,15 +199,15 @@ void exti_software_interrupt_disable(exti_line_enum linex) */ FlagStatus exti_flag_get(exti_line_enum linex) { - if(RESET != (EXTI_PD & (uint32_t)linex)){ + if(RESET != (EXTI_PD & (uint32_t)linex)) { return SET; - }else{ + } else { return RESET; - } + } } /*! - \brief clear EXTI lines pending flag + \brief clear EXTI line x interrupt pending flag \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -221,7 +220,7 @@ void exti_flag_clear(exti_line_enum linex) } /*! - \brief get EXTI lines flag when the interrupt flag is set + \brief get EXTI line x interrupt pending flag \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -230,20 +229,15 @@ void exti_flag_clear(exti_line_enum linex) */ FlagStatus exti_interrupt_flag_get(exti_line_enum linex) { - uint32_t flag_left, flag_right; - - flag_left = EXTI_PD & (uint32_t)linex; - flag_right = EXTI_INTEN & (uint32_t)linex; - - if((RESET != flag_left) && (RESET != flag_right)){ + if(RESET != (EXTI_PD & (uint32_t)linex)) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear EXTI lines pending flag + \brief clear EXTI line x interrupt pending flag \param[in] linex: EXTI line number, refer to exti_line_enum only one parameter can be selected which is shown as below: \arg EXTI_x (x=0..22): EXTI line x @@ -254,4 +248,3 @@ void exti_interrupt_flag_clear(exti_line_enum linex) { EXTI_PD = (uint32_t)linex; } - diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c index b5cd2fa..68d6b92 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c @@ -2,35 +2,33 @@ \file gd32f4xx_fmc.c \brief FMC driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -38,7 +36,7 @@ OF SUCH DAMAGE. #include "gd32f4xx_fmc.h" /*! - \brief set the wait state counter value + \brief set the FMC wait state counter \param[in] wscnt: wait state counter value only one parameter can be selected which is shown as below: \arg WS_WSCNT_0: FMC 0 wait @@ -63,7 +61,7 @@ OF SUCH DAMAGE. void fmc_wscnt_set(uint32_t wscnt) { uint32_t reg; - + reg = FMC_WS; /* set the wait state counter value */ reg &= ~FMC_WC_WSCNT; @@ -78,7 +76,7 @@ void fmc_wscnt_set(uint32_t wscnt) */ void fmc_unlock(void) { - if((RESET != (FMC_CTL & FMC_CTL_LK))){ + if((RESET != (FMC_CTL & FMC_CTL_LK))) { /* write the FMC key */ FMC_KEY = UNLOCK_KEY0; FMC_KEY = UNLOCK_KEY1; @@ -97,38 +95,84 @@ void fmc_lock(void) FMC_CTL |= FMC_CTL_LK; } +#if defined (GD32F425) || defined (GD32F427) || defined (GD32F470) + +/*! + \brief FMC erase page + \param[in] page_addr: the page address to be erased. + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_page_erase(uint32_t page_addr) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* unlock page erase operation */ + FMC_PEKEY = UNLOCK_PE_KEY; + + /* start page erase */ + FMC_PECFG = FMC_PE_EN | page_addr; + FMC_CTL &= ~FMC_CTL_SN; + FMC_CTL |= FMC_CTL_SER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + FMC_PECFG &= ~FMC_PE_EN; + FMC_CTL &= ~FMC_CTL_SER; + } + + /* return the FMC state */ + return fmc_state; +} + +#endif + /*! - \brief erase sector + \brief FMC erase sector \param[in] fmc_sector: select the sector to erase only one parameter can be selected which is shown as below: - \arg CTL_SECTOR_NUMBER_0: sector 0 - \arg CTL_SECTOR_NUMBER_1: sector 1 - \arg CTL_SECTOR_NUMBER_2: sector 2 - \arg CTL_SECTOR_NUMBER_3: sector 3 - \arg CTL_SECTOR_NUMBER_4: sector 4 - \arg CTL_SECTOR_NUMBER_5: sector 5 - \arg CTL_SECTOR_NUMBER_6: sector 6 - \arg CTL_SECTOR_NUMBER_7: sector 7 - \arg CTL_SECTOR_NUMBER_8: sector 8 - \arg CTL_SECTOR_NUMBER_9: sector 9 - \arg CTL_SECTOR_NUMBER_10: sector 10 - \arg CTL_SECTOR_NUMBER_11: sector 11 - \arg CTL_SECTOR_NUMBER_12: sector 12 - \arg CTL_SECTOR_NUMBER_13: sector 13 - \arg CTL_SECTOR_NUMBER_14: sector 14 - \arg CTL_SECTOR_NUMBER_15: sector 15 - \arg CTL_SECTOR_NUMBER_16: sector 16 - \arg CTL_SECTOR_NUMBER_17: sector 17 - \arg CTL_SECTOR_NUMBER_18: sector 18 - \arg CTL_SECTOR_NUMBER_19: sector 19 - \arg CTL_SECTOR_NUMBER_20: sector 20 - \arg CTL_SECTOR_NUMBER_21: sector 21 - \arg CTL_SECTOR_NUMBER_22: sector 22 - \arg CTL_SECTOR_NUMBER_23: sector 23 - \arg CTL_SECTOR_NUMBER_24: sector 24 - \arg CTL_SECTOR_NUMBER_25: sector 25 - \arg CTL_SECTOR_NUMBER_26: sector 26 - \arg CTL_SECTOR_NUMBER_27: sector 27 + \arg CTL_SECTOR_NUMBER_0: sector 0 + \arg CTL_SECTOR_NUMBER_1: sector 1 + \arg CTL_SECTOR_NUMBER_2: sector 2 + \arg CTL_SECTOR_NUMBER_3: sector 3 + \arg CTL_SECTOR_NUMBER_4: sector 4 + \arg CTL_SECTOR_NUMBER_5: sector 5 + \arg CTL_SECTOR_NUMBER_6: sector 6 + \arg CTL_SECTOR_NUMBER_7: sector 7 + \arg CTL_SECTOR_NUMBER_8: sector 8 + \arg CTL_SECTOR_NUMBER_9: sector 9 + \arg CTL_SECTOR_NUMBER_10: sector 10 + \arg CTL_SECTOR_NUMBER_11: sector 11 + \arg CTL_SECTOR_NUMBER_12: sector 12 + \arg CTL_SECTOR_NUMBER_13: sector 13 + \arg CTL_SECTOR_NUMBER_14: sector 14 + \arg CTL_SECTOR_NUMBER_15: sector 15 + \arg CTL_SECTOR_NUMBER_16: sector 16 + \arg CTL_SECTOR_NUMBER_17: sector 17 + \arg CTL_SECTOR_NUMBER_18: sector 18 + \arg CTL_SECTOR_NUMBER_19: sector 19 + \arg CTL_SECTOR_NUMBER_20: sector 20 + \arg CTL_SECTOR_NUMBER_21: sector 21 + \arg CTL_SECTOR_NUMBER_22: sector 22 + \arg CTL_SECTOR_NUMBER_23: sector 23 + \arg CTL_SECTOR_NUMBER_24: sector 24 + \arg CTL_SECTOR_NUMBER_25: sector 25 + \arg CTL_SECTOR_NUMBER_26: sector 26 + \arg CTL_SECTOR_NUMBER_27: sector 27 \param[out] none \retval state of FMC \arg FMC_READY: the operation has been completed @@ -138,7 +182,6 @@ void fmc_lock(void) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) @@ -147,7 +190,7 @@ fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* start sector erase */ FMC_CTL &= ~FMC_CTL_SN; FMC_CTL |= (FMC_CTL_SER | fmc_sector); @@ -166,7 +209,7 @@ fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) } /*! - \brief erase whole chip + \brief FMC erase whole chip \param[in] none \param[out] none \retval state of FMC @@ -177,7 +220,6 @@ fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_mass_erase(void) @@ -186,7 +228,7 @@ fmc_state_enum fmc_mass_erase(void) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* start whole chip erase */ FMC_CTL |= (FMC_CTL_MER0 | FMC_CTL_MER1); FMC_CTL |= FMC_CTL_START; @@ -203,7 +245,7 @@ fmc_state_enum fmc_mass_erase(void) } /*! - \brief erase all FMC sectors in bank0 + \brief FMC erase whole bank0 \param[in] none \param[out] none \retval state of FMC @@ -214,7 +256,6 @@ fmc_state_enum fmc_mass_erase(void) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_bank0_erase(void) @@ -223,7 +264,7 @@ fmc_state_enum fmc_bank0_erase(void) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* start FMC bank0 erase */ FMC_CTL |= FMC_CTL_MER0; FMC_CTL |= FMC_CTL_START; @@ -240,7 +281,7 @@ fmc_state_enum fmc_bank0_erase(void) } /*! - \brief erase all FMC sectors in bank1 + \brief FMC erase whole bank1 \param[in] none \param[out] none \retval state of FMC @@ -251,7 +292,6 @@ fmc_state_enum fmc_bank0_erase(void) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_bank1_erase(void) @@ -260,7 +300,7 @@ fmc_state_enum fmc_bank1_erase(void) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* start FMC bank1 erase */ FMC_CTL |= FMC_CTL_MER1; FMC_CTL |= FMC_CTL_START; @@ -289,7 +329,6 @@ fmc_state_enum fmc_bank1_erase(void) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) @@ -298,11 +337,11 @@ fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* set the PG bit to start program */ FMC_CTL &= ~FMC_CTL_PSZ; FMC_CTL |= CTL_PSZ_WORD; - FMC_CTL |= FMC_CTL_PG; + FMC_CTL |= FMC_CTL_PG; REG32(address) = data; @@ -330,7 +369,6 @@ fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) @@ -339,7 +377,7 @@ fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { /* set the PG bit to start program */ FMC_CTL &= ~FMC_CTL_PSZ; FMC_CTL |= CTL_PSZ_HALF_WORD; @@ -371,7 +409,6 @@ fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data) @@ -379,8 +416,8 @@ fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data) fmc_state_enum fmc_state = FMC_READY; /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - - if(FMC_READY == fmc_state){ + + if(FMC_READY == fmc_state) { /* set the PG bit to start program */ FMC_CTL &= ~FMC_CTL_PSZ; FMC_CTL |= CTL_PSZ_BYTE; @@ -407,7 +444,7 @@ fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data) */ void ob_unlock(void) { - if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)){ + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)) { /* write the FMC key */ FMC_OBKEY = OB_UNLOCK_KEY0; FMC_OBKEY = OB_UNLOCK_KEY1; @@ -434,14 +471,8 @@ void ob_lock(void) */ void ob_start(void) { - fmc_state_enum fmc_state = FMC_READY; /* set the OB_START bit in OBCTL0 register */ FMC_OBCTL0 |= FMC_OBCTL0_OB_START; - fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY != fmc_state){ - while(1){ - } - } } /*! @@ -456,10 +487,10 @@ void ob_erase(void) fmc_state_enum fmc_state = FMC_READY; /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + reg = FMC_OBCTL0; + reg1 = FMC_OBCTL1; - if(FMC_READY == fmc_state){ - reg = FMC_OBCTL0; - reg1 = FMC_OBCTL1; + if(FMC_READY == fmc_state) { /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */ reg |= (FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY); @@ -490,25 +521,28 @@ void ob_erase(void) \arg OB_WP_23_27: sector23~27 \arg OB_WP_ALL: all sector \param[out] none - \retval none + \retval SUCCESS or ERROR */ -void ob_write_protection_enable(uint32_t ob_wp) +ErrStatus ob_write_protection_enable(uint32_t ob_wp) { uint32_t reg0 = FMC_OBCTL0; uint32_t reg1 = FMC_OBCTL1; fmc_state_enum fmc_state = FMC_READY; - if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)){ - while(1){ - } + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)) { + return ERROR; } /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ - reg0 &= (~((uint32_t)ob_wp << 16)); + if(FMC_READY == fmc_state) { + reg0 &= (~((uint32_t)ob_wp << 16U)); reg1 &= (~(ob_wp & 0xFFFF0000U)); FMC_OBCTL0 = reg0; FMC_OBCTL1 = reg1; + + return SUCCESS; + } else { + return ERROR; } } @@ -520,31 +554,34 @@ void ob_write_protection_enable(uint32_t ob_wp) \arg OB_WP_23_27: sector23~27 \arg OB_WP_ALL: all sector \param[out] none - \retval none + \retval SUCCESS or ERROR */ -void ob_write_protection_disable(uint32_t ob_wp) +ErrStatus ob_write_protection_disable(uint32_t ob_wp) { uint32_t reg0 = FMC_OBCTL0; uint32_t reg1 = FMC_OBCTL1; fmc_state_enum fmc_state = FMC_READY; - if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)){ - while(1){ - } + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)) { + return ERROR; } /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ - reg0 |= ((uint32_t)ob_wp << 16); + if(FMC_READY == fmc_state) { + reg0 |= ((uint32_t)ob_wp << 16U); reg1 |= (ob_wp & 0xFFFF0000U); FMC_OBCTL0 = reg0; FMC_OBCTL1 = reg1; + + return SUCCESS; + } else { + return ERROR; } } /*! \brief enable erase/program protection and D-bus read protection - \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector + \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector one or more parameters can be selected which are shown as below: \arg OB_DRP_x(x=0..22): sector x(x = 0,1,2...22) \arg OB_DRP_23_27: sector23~27 @@ -558,38 +595,31 @@ void ob_drp_enable(uint32_t ob_drp) uint32_t reg1 = FMC_OBCTL1; fmc_state_enum fmc_state = FMC_READY; uint32_t drp_state = FMC_OBCTL0 & FMC_OBCTL0_DRP; - uint32_t wp0_state = FMC_OBCTL0 & FMC_OBCTL0_WP0; - uint32_t wp1_state = FMC_OBCTL1 & FMC_OBCTL1_WP1; - /*disable write protection before enable D-bus read protection*/ - if((RESET != drp_state) && ((FMC_OBCTL0_WP0 != wp0_state) && (FMC_OBCTL1_WP1 != wp1_state))){ - while(1){ - } - } + /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ - reg0 &= ~FMC_OBCTL0_WP0; - reg1 &= ~FMC_OBCTL1_WP1; - reg0 |= ((uint32_t)ob_drp << 16); + if(FMC_READY == fmc_state) { + if(RESET == drp_state) { + reg0 &= ~FMC_OBCTL0_WP0; + reg1 &= ~FMC_OBCTL1_WP1; + } + reg0 |= ((uint32_t)ob_drp << 16U); + reg0 |= FMC_OBCTL0_DRP; reg1 |= ((uint32_t)ob_drp & 0xFFFF0000U); + FMC_OBCTL0 = reg0; FMC_OBCTL1 = reg1; - FMC_OBCTL0 |= FMC_OBCTL0_DRP; } } /*! \brief disable erase/program protection and D-bus read protection - \param[in] ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector - one or more parameters can be selected which are shown as below: - \arg OB_DRP_x(x=0..22): sector x(x = 0,1,2...22) - \arg OB_DRP_23_27: sector23~27 - \arg OB_DRP_ALL: all sector + \param[in] none \param[out] none \retval none */ -void ob_drp_disable(uint32_t ob_drp) +void ob_drp_disable(void) { uint32_t reg0 = FMC_OBCTL0; uint32_t reg1 = FMC_OBCTL1; @@ -597,27 +627,26 @@ void ob_drp_disable(uint32_t ob_drp) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ - if(((uint8_t)(reg0 >> 8)) == (uint8_t)FMC_NSPC){ + if(FMC_READY == fmc_state) { + if(((uint8_t)(reg0 >> 8U)) == (uint8_t)FMC_NSPC) { /* security protection should be set as low level protection before disable D-BUS read protection */ reg0 &= ~FMC_OBCTL0_SPC; - reg0 |= ((uint32_t)FMC_LSPC << 8); + reg0 |= ((uint32_t)FMC_LSPC << 8U); FMC_OBCTL0 = reg0; - ob_start(); - while(FMC_READY != fmc_ready_wait(FMC_TIMEOUT_COUNT)); - }else if(((uint8_t)(reg0 >> 8)) == (uint8_t)FMC_HSPC){ - return; + /* set the OB_START bit in OBCTL0 register */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_START; } /* it is necessary to disable the security protection at the same time when D-BUS read protection is disabled */ reg0 &= ~FMC_OBCTL0_SPC; - reg0 |= ((uint32_t)FMC_NSPC << 8); + reg0 |= ((uint32_t)FMC_NSPC << 8U); reg0 |= FMC_OBCTL0_WP0; reg0 &= (~FMC_OBCTL0_DRP); FMC_OBCTL0 = reg0; reg1 |= FMC_OBCTL1_WP1; FMC_OBCTL1 = reg1; + } } @@ -637,19 +666,19 @@ void ob_security_protection_config(uint8_t ob_spc) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { uint32_t reg; reg = FMC_OBCTL0; /* reset the OBCTL0_SPC, set according to ob_spc */ reg &= ~FMC_OBCTL0_SPC; - reg |= ((uint32_t)ob_spc << 8); + reg |= ((uint32_t)ob_spc << 8U); FMC_OBCTL0 = reg; } } /*! - \brief program the FMC user option byte + \brief program the FMC user option byte \param[in] ob_fwdgt: option byte watchdog value only one parameter can be selected which is shown as below: \arg OB_FWDGT_SW: software free watchdog @@ -657,11 +686,11 @@ void ob_security_protection_config(uint8_t ob_spc) \param[in] ob_deepsleep: option byte deepsleep reset value only one parameter can be selected which is shown as below: \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode - \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode + \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode \param[in] ob_stdby:option byte standby reset value only one parameter can be selected which is shown as below: \arg OB_STDBY_NRST: no reset when entering standby mode - \arg OB_STDBY_RST: generate a reset instead of entering standby mode + \arg OB_STDBY_RST: generate a reset instead of entering standby mode \param[out] none \retval none */ @@ -672,7 +701,7 @@ void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby) /* wait for the FMC ready */ fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); - if(FMC_READY == fmc_state){ + if(FMC_READY == fmc_state) { uint32_t reg; reg = FMC_OBCTL0; @@ -696,7 +725,7 @@ void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby) void ob_user_bor_threshold(uint32_t ob_bor_th) { uint32_t reg; - + reg = FMC_OBCTL0; /* set the BOR level */ reg &= ~FMC_OBCTL0_BOR_TH; @@ -715,13 +744,34 @@ void ob_user_bor_threshold(uint32_t ob_bor_th) void ob_boot_mode_config(uint32_t boot_mode) { uint32_t reg; - + reg = FMC_OBCTL0; /* set option byte boot bank value */ reg &= ~FMC_OBCTL0_BB; FMC_OBCTL0 = (reg | boot_mode); } +#if defined (GD32F450) || defined (GD32F470) +/*! + \brief configure the option byte double bank select, only for 1MB flash memory series + \param[in] double_bank: specifies the option byte double bank select + only one parameter can be selected which is shown as below: + \arg OB_DBS_DISABLE: single bank when flash size is 1M bytes + \arg OB_DBS_ENABLE: double banks when flash size is 1M bytes + \param[out] none + \retval none +*/ +void ob_double_bank_select(uint32_t double_bank) +{ + uint32_t reg; + + reg = FMC_OBCTL0; + /* set option byte double bank select */ + reg &= ~FMC_OBCTL0_DBS; + FMC_OBCTL0 = (reg | double_bank); +} +#endif + /*! \brief get the FMC user option byte \param[in] none @@ -730,7 +780,7 @@ void ob_boot_mode_config(uint32_t boot_mode) */ uint8_t ob_user_get(void) { - return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5) & (uint8_t)0x07); + return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5U) & 0x07U); } /*! @@ -742,7 +792,7 @@ uint8_t ob_user_get(void) uint16_t ob_write_protection0_get(void) { /* return the FMC write protection option byte value */ - return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF); + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16U)) & 0x0FFFU); } /*! @@ -754,11 +804,11 @@ uint16_t ob_write_protection0_get(void) uint16_t ob_write_protection1_get(void) { /* return the the FMC write protection option byte value */ - return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF); + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16U)) & 0x0FFFU); } /*! - \brief get the FMC D-bus read protection protection + \brief get the FMC erase/program protection and D-bus read protection option bytes value \param[in] none \param[out] none \retval the FMC erase/program protection and D-bus read protection option bytes value @@ -766,11 +816,15 @@ uint16_t ob_write_protection1_get(void) uint16_t ob_drp0_get(void) { /* return the FMC erase/program protection and D-bus read protection option bytes value */ - return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF); + if(FMC_OBCTL0 & FMC_OBCTL0_DRP) { + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16U)) & 0x0FFFU); + } else { + return 0xF000U; + } } /*! - \brief get the FMC D-bus read protection protection + \brief get the FMC erase/program protection and D-bus read protection option bytes value \param[in] none \param[out] none \retval the FMC erase/program protection and D-bus read protection option bytes value @@ -778,11 +832,15 @@ uint16_t ob_drp0_get(void) uint16_t ob_drp1_get(void) { /* return the FMC erase/program protection and D-bus read protection option bytes value */ - return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF); + if(FMC_OBCTL0 & FMC_OBCTL0_DRP) { + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16U)) & 0x0FFFU); + } else { + return 0xF000U; + } } /*! - \brief get the FMC option byte security protection + \brief get option byte security protection code value \param[in] none \param[out] none \retval FlagStatus: SET or RESET @@ -790,10 +848,10 @@ uint16_t ob_drp1_get(void) FlagStatus ob_spc_get(void) { FlagStatus spc_state = RESET; - - if (((uint8_t)(FMC_OBCTL0 >> 8)) != (uint8_t)FMC_NSPC){ + + if(((uint8_t)(FMC_OBCTL0 >> 8U)) != FMC_NSPC) { spc_state = SET; - }else{ + } else { spc_state = RESET; } return spc_state; @@ -808,7 +866,49 @@ FlagStatus ob_spc_get(void) uint8_t ob_user_bor_threshold_get(void) { /* return the FMC BOR threshold value */ - return (uint8_t)((uint8_t)FMC_OBCTL0 & (uint8_t)0x0C); + return (uint8_t)((uint8_t)FMC_OBCTL0 & 0x0CU); +} + +/*! + \brief get flag set or reset + \param[in] fmc_flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC busy flag bit + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t fmc_flag) +{ + if(FMC_STAT & fmc_flag) { + return SET; + } + /* return the state of corresponding FMC flag */ + return RESET; +} + +/*! + \brief clear the FMC pending flag + \param[in] FMC_flag: clear FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t fmc_flag) +{ + /* clear the flags */ + FMC_STAT = fmc_flag; } /*! @@ -840,45 +940,56 @@ void fmc_interrupt_disable(uint32_t fmc_int) } /*! - \brief get flag set or reset - \param[in] fmc_flag: check FMC flag + \brief get FMC interrupt flag set or reset + \param[in] fmc_int_flag: FMC interrupt flag only one parameter can be selected which is shown as below: - \arg FMC_FLAG_BUSY: FMC busy flag bit - \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit - \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit - \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit - \arg FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit - \arg FMC_FLAG_OPERR: FMC operation error flag bit - \arg FMC_FLAG_END: FMC end of operation flag bit + \arg FMC_INT_FLAG_RDDERR: FMC read D-bus protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: FMC program sequence error interrupt flag + \arg FMC_INT_FLAG_PGMERR: FMC program size not match error interrupt flag + \arg FMC_INT_FLAG_WPERR: FMC Erase/Program protection error interrupt flag + \arg FMC_INT_FLAG_OPERR: FMC operation error interrupt flag + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus fmc_flag_get(uint32_t fmc_flag) +FlagStatus fmc_interrupt_flag_get(uint32_t fmc_int_flag) { - if(FMC_STAT & fmc_flag){ - return SET; + if(FMC_FLAG_END == fmc_int_flag) { + /* end of operation interrupt flag */ + if(FMC_CTL & FMC_CTL_ENDIE) { + if(FMC_STAT & fmc_int_flag) { + return SET; + } + } + } else { + /* error interrupt flags */ + if(FMC_CTL & FMC_CTL_ERRIE) { + if(FMC_STAT & fmc_int_flag) { + return SET; + } + } } - /* return the state of corresponding FMC flag */ - return RESET; + + return RESET; } /*! - \brief clear the FMC pending flag - \param[in] FMC_flag: clear FMC flag + \brief clear the FMC interrupt flag + \param[in] fmc_int_flag: FMC interrupt flag only one parameter can be selected which is shown as below: - \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit - \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit - \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit - \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit - \arg FMC_FLAG_OPERR: FMC operation error flag bit - \arg FMC_FLAG_END: FMC end of operation flag bit + \arg FMC_INT_FLAG_RDDERR: FMC read D-bus protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: FMC program sequence error interrupt flag + \arg FMC_INT_FLAG_PGMERR: FMC program size not match error interrupt flag + \arg FMC_INT_FLAG_WPERR: FMC Erase/Program protection error interrupt flag + \arg FMC_INT_FLAG_OPERR: FMC operation error interrupt flag + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag \param[out] none \retval none */ -void fmc_flag_clear(uint32_t fmc_flag) +void fmc_interrupt_flag_clear(uint32_t fmc_int_flag) { - /* clear the flags */ - FMC_STAT = fmc_flag; + /* clear the interrupt flag */ + FMC_STAT = fmc_int_flag; } /*! @@ -893,33 +1004,28 @@ void fmc_flag_clear(uint32_t fmc_flag) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error */ fmc_state_enum fmc_state_get(void) { fmc_state_enum fmc_state = FMC_READY; - - if((FMC_STAT & FMC_FLAG_BUSY) == FMC_FLAG_BUSY){ + uint32_t temp_val = FMC_STAT; + + if(RESET != (temp_val & FMC_FLAG_BUSY)) { fmc_state = FMC_BUSY; - }else{ - if((FMC_STAT & FMC_FLAG_WPERR) != (uint32_t)0x00){ - fmc_state = FMC_WPERR; - }else{ - if((FMC_STAT & FMC_FLAG_RDDERR) != (uint32_t)0x00){ - fmc_state = FMC_RDDERR; - }else{ - if((FMC_STAT & (uint32_t)0xEF) != (uint32_t)0x00){ - fmc_state = FMC_PGERR; - }else{ - if((FMC_STAT & FMC_FLAG_OPERR) != (uint32_t)0x00){ - fmc_state = FMC_OPERR; - }else{ - fmc_state = FMC_READY; - } - } - } - } + } else if(RESET != (temp_val & FMC_FLAG_RDDERR)) { + fmc_state = FMC_RDDERR; + } else if(RESET != (temp_val & FMC_FLAG_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if(RESET != (temp_val & FMC_FLAG_PGMERR)) { + fmc_state = FMC_PGMERR; + } else if(RESET != (temp_val & FMC_FLAG_WPERR)) { + fmc_state = FMC_WPERR; + } else if(RESET != (temp_val & FMC_FLAG_OPERR)) { + fmc_state = FMC_OPERR; + } else { + fmc_state = FMC_READY; } + /* return the FMC state */ return fmc_state; } @@ -936,7 +1042,6 @@ fmc_state_enum fmc_state_get(void) \arg FMC_PGMERR: program size not match error \arg FMC_WPERR: erase/program protection error \arg FMC_OPERR: operation error - \arg FMC_PGERR: program error \arg FMC_TOERR: timeout error */ fmc_state_enum fmc_ready_wait(uint32_t timeout) @@ -944,15 +1049,16 @@ fmc_state_enum fmc_ready_wait(uint32_t timeout) fmc_state_enum fmc_state = FMC_BUSY; /* wait for FMC ready */ - do{ + do { /* get FMC state */ fmc_state = fmc_state_get(); timeout--; - }while((FMC_BUSY == fmc_state) && (0U != timeout)); + } while((FMC_BUSY == fmc_state) && (0U != timeout)); - if(FMC_BUSY == fmc_state){ + if(0U == timeout) { fmc_state = FMC_TOERR; } + /* return the FMC state */ return fmc_state; } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c index 30fc5ef..27b479b 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c @@ -1,14 +1,12 @@ /*! \file gd32f4xx_fwdgt.c \brief FWDGT driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -36,11 +34,6 @@ OF SUCH DAMAGE. #include "gd32f4xx_fwdgt.h" -/* write value to FWDGT_CTL_CMD bit field */ -#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) -/* write value to FWDGT_RLD_RLD bit field */ -#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) - /*! \brief enable write access to FWDGT_PSC and FWDGT_RLD \param[in] none @@ -74,6 +67,71 @@ void fwdgt_enable(void) FWDGT_CTL = FWDGT_KEY_ENABLE; } +/*! + \brief configure the free watchdog timer counter prescaler value + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return SUCCESS; +} + /*! \brief reload the counter of FWDGT \param[in] none diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c index 9f8fd84..1e641d0 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c @@ -1,44 +1,42 @@ /*! \file gd32f4xx_gpio.c \brief GPIO driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_gpio.h" /*! - \brief reset GPIO port - \param[in] gpio_periph: GPIO port + \brief reset GPIO port + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[out] none @@ -46,7 +44,7 @@ OF SUCH DAMAGE. */ void gpio_deinit(uint32_t gpio_periph) { - switch(gpio_periph){ + switch(gpio_periph) { case GPIOA: /* reset GPIOA */ rcu_periph_reset_enable(RCU_GPIOARST); @@ -98,8 +96,8 @@ void gpio_deinit(uint32_t gpio_periph) } /*! - \brief set GPIO mode - \param[in] gpio_periph: GPIO port + \brief set GPIO mode + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] mode: GPIO pin mode @@ -125,8 +123,8 @@ void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, u ctl = GPIO_CTL(gpio_periph); pupd = GPIO_PUD(gpio_periph); - for(i = 0U;i < 16U;i++){ - if((1U << i) & pin){ + for(i = 0U; i < 16U; i++) { + if((1U << i) & pin) { /* clear the specified pin mode bits */ ctl &= ~GPIO_MODE_MASK(i); /* set the specified pin mode bits */ @@ -144,18 +142,18 @@ void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, u } /*! - \brief set GPIO output type and speed - \param[in] gpio_periph: GPIO port + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] otype: GPIO pin output mode \arg GPIO_OTYPE_PP: push pull mode \arg GPIO_OTYPE_OD: open drain mode \param[in] speed: GPIO pin output max speed - \arg GPIO_OSPEED_2MHZ: output max speed 2MHz - \arg GPIO_OSPEED_25MHZ: output max speed 25MHz + \arg GPIO_OSPEED_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_25MHZ: output max speed 25MHz \arg GPIO_OSPEED_50MHZ: output max speed 50MHz - \arg GPIO_OSPEED_200MHZ: output max speed 200MHz + \arg GPIO_OSPEED_MAX: output max speed more than 50MHz \param[in] pin: GPIO pin one or more parameters can be selected which are shown as below: \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL @@ -167,21 +165,21 @@ void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed uint16_t i; uint32_t ospeedr; - if(GPIO_OTYPE_OD == otype){ + if(GPIO_OTYPE_OD == otype) { GPIO_OMODE(gpio_periph) |= (uint32_t)pin; - }else{ + } else { GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); } /* get the specified pin output speed bits value */ ospeedr = GPIO_OSPD(gpio_periph); - for(i = 0U;i < 16U;i++){ - if((1U << i) & pin){ + for(i = 0U; i < 16U; i++) { + if((1U << i) & pin) { /* clear the specified pin output speed bits */ ospeedr &= ~GPIO_OSPEED_MASK(i); /* set the specified pin output speed bits */ - ospeedr |= GPIO_OSPEED_SET(i,speed); + ospeedr |= GPIO_OSPEED_SET(i, speed); } } GPIO_OSPD(gpio_periph) = ospeedr; @@ -189,7 +187,7 @@ void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed /*! \brief set GPIO pin bit - \param[in] gpio_periph: GPIO port + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -204,8 +202,8 @@ void gpio_bit_set(uint32_t gpio_periph, uint32_t pin) } /*! - \brief reset GPIO pin bit - \param[in] gpio_periph: GPIO port + \brief reset GPIO pin bit + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -220,8 +218,8 @@ void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) } /*! - \brief write data to the specified GPIO pin - \param[in] gpio_periph: GPIO port + \brief write data to the specified GPIO pin + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -235,16 +233,16 @@ void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) */ void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value) { - if(RESET != bit_value){ + if(RESET != bit_value) { GPIO_BOP(gpio_periph) = (uint32_t)pin; - }else{ + } else { GPIO_BC(gpio_periph) = (uint32_t)pin; } } /*! - \brief write data to the specified GPIO port - \param[in] gpio_periph: GPIO port + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] data: specify the value to be written to the port output control register @@ -257,8 +255,8 @@ void gpio_port_write(uint32_t gpio_periph, uint16_t data) } /*! - \brief get GPIO pin input status - \param[in] gpio_periph: GPIO port + \brief get GPIO pin input status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -269,16 +267,16 @@ void gpio_port_write(uint32_t gpio_periph, uint16_t data) */ FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin) { - if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ - return SET; - }else{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph) & (pin))) { + return SET; + } else { return RESET; } } /*! - \brief get GPIO all pins input status - \param[in] gpio_periph: GPIO port + \brief get GPIO all pins input status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[out] none @@ -290,8 +288,8 @@ uint16_t gpio_input_port_get(uint32_t gpio_periph) } /*! - \brief get GPIO pin output status - \param[in] gpio_periph: GPIO port + \brief get GPIO pin output status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -302,18 +300,18 @@ uint16_t gpio_input_port_get(uint32_t gpio_periph) */ FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin) { - if((uint32_t)RESET !=(GPIO_OCTL(gpio_periph)&(pin))){ + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph) & (pin))) { return SET; - }else{ + } else { return RESET; } } /*! - \brief get GPIO all pins output status - \param[in] gpio_periph: GPIO port + \brief get GPIO port output status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: - \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[out] none \retval output status of GPIO all pins */ @@ -323,8 +321,8 @@ uint16_t gpio_output_port_get(uint32_t gpio_periph) } /*! - \brief set GPIO alternate function - \param[in] gpio_periph: GPIO port + \brief set GPIO alternate function + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] alt_func_num: GPIO pin af function @@ -334,10 +332,10 @@ uint16_t gpio_output_port_get(uint32_t gpio_periph) \arg GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10 \arg GPIO_AF_4: I2C0, I2C1, I2C2 \arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5 - \arg GPIO_AF_6: SPI1, SPI2, SAI0, SPI3, SPI4 + \arg GPIO_AF_6: SPI2, SPI3, SPI4 \arg GPIO_AF_7: USART0, USART1, USART2, SPI1, SPI2 \arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7 - \arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13 + \arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13, I2C1, I2C2, CTC \arg GPIO_AF_10: USB_FS, USB_HS \arg GPIO_AF_11: ENET \arg GPIO_AF_12: EXMC, SDIO, USB_HS @@ -358,19 +356,19 @@ void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin) afrl = GPIO_AFSEL0(gpio_periph); afrh = GPIO_AFSEL1(gpio_periph); - for(i = 0U;i < 8U;i++){ - if((1U << i) & pin){ + for(i = 0U; i < 8U; i++) { + if((1U << i) & pin) { /* clear the specified pin alternate function bits */ afrl &= ~GPIO_AFR_MASK(i); - afrl |= GPIO_AFR_SET(i,alt_func_num); + afrl |= GPIO_AFR_SET(i, alt_func_num); } } - for(i = 8U;i < 16U;i++){ - if((1U << i) & pin){ + for(i = 8U; i < 16U; i++) { + if((1U << i) & pin) { /* clear the specified pin alternate function bits */ afrh &= ~GPIO_AFR_MASK(i - 8U); - afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + afrh |= GPIO_AFR_SET(i - 8U, alt_func_num); } } @@ -379,8 +377,8 @@ void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin) } /*! - \brief lock GPIO pin bit - \param[in] gpio_periph: GPIO port + \brief lock GPIO pin bit + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -403,8 +401,8 @@ void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin) } /*! - \brief toggle GPIO pin status - \param[in] gpio_periph: GPIO port + \brief toggle GPIO pin status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) \param[in] pin: GPIO pin @@ -419,8 +417,8 @@ void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin) } /*! - \brief toggle GPIO port status - \param[in] gpio_periph: GPIO port + \brief toggle GPIO port status + \param[in] gpio_periph: GPIO port only one parameter can be selected which is shown as below: \arg GPIOx(x = A,B,C,D,E,F,G,H,I) diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c index c9de1db..0323cb7 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c @@ -2,60 +2,57 @@ \file gd32f4xx_i2c.c \brief I2C driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2019-04-16, V2.0.2, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_i2c.h" /* I2C register bit mask */ -#define I2CCLK_MAX ((uint32_t)0x00000032U) /*!< i2cclk maximum value */ +#define I2CCLK_MAX ((uint32_t)0x0000003CU) /*!< i2cclk maximum value */ #define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */ #define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */ #define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ #define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */ /* I2C register bit offset */ -#define STAT1_PECV_OFFSET ((uint32_t)8U) /* bit offset of PECV in I2C_STAT1 */ +#define STAT1_PECV_OFFSET ((uint32_t)0x00000008U) /* bit offset of PECV in I2C_STAT1 */ /*! - \brief reset I2C + \brief reset I2C \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_deinit(uint32_t i2c_periph) { - switch(i2c_periph){ + switch(i2c_periph) { case I2C0: /* reset I2C0 */ rcu_periph_reset_enable(RCU_I2C0RST); @@ -77,13 +74,13 @@ void i2c_deinit(uint32_t i2c_periph) } /*! - \brief configure I2C clock + \brief configure I2C clock \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) \param[in] dutycyc: duty cycle in fast mode only one parameter can be selected which is shown as below: - \arg I2C_DTCY_2: T_low/T_high=2 - \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \arg I2C_DTCY_2: T_low/T_high = 2 in fast mode + \arg I2C_DTCY_16_9: T_low/T_high = 16/9 in fast mode \param[out] none \retval none */ @@ -91,59 +88,61 @@ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) { uint32_t pclk1, clkc, freq, risetime; uint32_t temp; - + pclk1 = rcu_clock_freq_get(CK_APB1); /* I2C peripheral clock frequency */ - freq = (uint32_t)(pclk1/1000000U); - if(freq >= I2CCLK_MAX){ + freq = (uint32_t)(pclk1 / 1000000U); + if(freq >= I2CCLK_MAX) { freq = I2CCLK_MAX; } temp = I2C_CTL1(i2c_periph); temp &= ~I2C_CTL1_I2CCLK; temp |= freq; - + I2C_CTL1(i2c_periph) = temp; - - if(100000U >= clkspeed){ + + if(100000U >= clkspeed) { /* the maximum SCL rise time is 1000ns in standard mode */ - risetime = (uint32_t)((pclk1/1000000U)+1U); - if(risetime >= I2CCLK_MAX){ + risetime = (uint32_t)((pclk1 / 1000000U) + 1U); + if(risetime >= I2CCLK_MAX) { I2C_RT(i2c_periph) = I2CCLK_MAX; - }else{ + } else if(risetime <= I2CCLK_MIN) { + I2C_RT(i2c_periph) = I2CCLK_MIN; + } else { I2C_RT(i2c_periph) = risetime; } - clkc = (uint32_t)(pclk1/(clkspeed*2U)); - if(clkc < 0x04U){ + clkc = (uint32_t)(pclk1 / (clkspeed * 2U)); + if(clkc < 0x04U) { /* the CLKC in standard mode minmum value is 4 */ clkc = 0x04U; } - + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); - }else if(400000U >= clkspeed){ + } else if(400000U >= clkspeed) { /* the maximum SCL rise time is 300ns in fast mode */ - I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U); - if(I2C_DTCY_2 == dutycyc){ + I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U); + if(I2C_DTCY_2 == dutycyc) { /* I2C duty cycle is 2 */ - clkc = (uint32_t)(pclk1/(clkspeed*3U)); + clkc = (uint32_t)(pclk1 / (clkspeed * 3U)); I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; - }else{ + } else { /* I2C duty cycle is 16/9 */ - clkc = (uint32_t)(pclk1/(clkspeed*25U)); + clkc = (uint32_t)(pclk1 / (clkspeed * 25U)); I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; } - if(0U == (clkc & I2C_CKCFG_CLKC)){ + if(0U == (clkc & I2C_CKCFG_CLKC)) { /* the CLKC in fast mode minmum value is 1 */ - clkc |= 0x0001U; + clkc |= 0x0001U; } I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; I2C_CKCFG(i2c_periph) |= clkc; - }else{ + } else { } } /*! - \brief configure I2C address + \brief configure I2C address \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] mode: only one parameter can be selected which is shown as below: @@ -151,8 +150,8 @@ void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) \arg I2C_SMBUSMODE_ENABLE: SMBus mode \param[in] addformat: 7bits or 10bits only one parameter can be selected which is shown as below: - \arg I2C_ADDFORMAT_7BITS: 7bits - \arg I2C_ADDFORMAT_10BITS: 10bits + \arg I2C_ADDFORMAT_7BITS: address format is 7 bits + \arg I2C_ADDFORMAT_10BITS: address format is 10 bits \param[in] addr: I2C address \param[out] none \retval none @@ -161,9 +160,9 @@ void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat { /* SMBus/I2C mode selected */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); - ctl &= ~(I2C_CTL0_SMBEN); + ctl &= ~(I2C_CTL0_SMBEN); ctl |= mode; I2C_CTL0(i2c_periph) = ctl; /* configure address */ @@ -172,26 +171,26 @@ void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat } /*! - \brief SMBus type selection + \brief select SMBus type \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] type: only one parameter can be selected which is shown as below: - \arg I2C_SMBUS_DEVICE: device - \arg I2C_SMBUS_HOST: host + \arg I2C_SMBUS_DEVICE: SMBus mode device type + \arg I2C_SMBUS_HOST: SMBus mode host type \param[out] none \retval none */ void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) { - if(I2C_SMBUS_HOST == type){ + if(I2C_SMBUS_HOST == type) { I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; - }else{ + } else { I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); } } /*! - \brief whether or not to send an ACK + \brief whether or not to send an ACK \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] ack: only one parameter can be selected which is shown as below: @@ -202,50 +201,51 @@ void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) */ void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) { - if(I2C_ACK_ENABLE == ack){ - I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; - }else{ - I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); - } + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ACKEN); + ctl |= ack; + I2C_CTL0(i2c_periph) = ctl; } /*! - \brief configure I2C POAP position + \brief configure I2C POAP position \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] pos: only one parameter can be selected which is shown as below: - \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current - \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \arg I2C_ACKPOS_CURRENT: ACKEN bit decides whether or not to send ACK or not for the current byte + \arg I2C_ACKPOS_NEXT: ACKEN bit decides whether or not to send ACK for the next byte \param[out] none \retval none */ void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) { + uint32_t ctl = 0U; /* configure I2C POAP position */ - if(I2C_ACKPOS_NEXT == pos){ - I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; - }else{ - I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); - } + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_POAP); + ctl |= pos; + I2C_CTL0(i2c_periph) = ctl; } /*! - \brief master sends slave address + \brief master sends slave address \param[in] i2c_periph: I2Cx(x=0,1,2) - \param[in] addr: slave address + \param[in] addr: slave address \param[in] trandirection: transmitter or receiver only one parameter can be selected which is shown as below: - \arg I2C_TRANSMITTER: transmitter - \arg I2C_RECEIVER: receiver + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver \param[out] none \retval none */ void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) { /* master is a transmitter or a receiver */ - if(I2C_TRANSMITTER == trandirection){ + if(I2C_TRANSMITTER == trandirection) { addr = addr & I2C_TRANSMITTER; - }else{ + } else { addr = addr | I2C_RECEIVER; } /* send slave address */ @@ -253,7 +253,7 @@ void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandire } /*! - \brief enable dual-address mode + \brief enable dual-address mode \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] addr: the second address in dual-address mode \param[out] none @@ -267,8 +267,8 @@ void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) } /*! - \brief disable dual-address mode - \param[in] i2c_periph: I2Cx(x=0,1,2) + \brief disable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ @@ -278,8 +278,8 @@ void i2c_dualaddr_disable(uint32_t i2c_periph) } /*! - \brief enable I2C - \param[in] i2c_periph: I2Cx(x=0,1,2) + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ @@ -289,8 +289,8 @@ void i2c_enable(uint32_t i2c_periph) } /*! - \brief disable I2C - \param[in] i2c_periph: I2Cx(x=0,1,2) + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ @@ -300,7 +300,7 @@ void i2c_disable(uint32_t i2c_periph) } /*! - \brief generate a START condition on I2C bus + \brief generate a START condition on I2C bus \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none @@ -311,7 +311,7 @@ void i2c_start_on_bus(uint32_t i2c_periph) } /*! - \brief generate a STOP condition on I2C bus + \brief generate a STOP condition on I2C bus \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none @@ -322,9 +322,9 @@ void i2c_stop_on_bus(uint32_t i2c_periph) } /*! - \brief I2C transmit data function + \brief I2C transmit data function \param[in] i2c_periph: I2Cx(x=0,1,2) - \param[in] data: data of transmission + \param[in] data: data of transmission \param[out] none \retval none */ @@ -334,7 +334,7 @@ void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) } /*! - \brief I2C receive data function + \brief I2C receive data function \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval data of received @@ -345,28 +345,28 @@ uint8_t i2c_data_receive(uint32_t i2c_periph) } /*! - \brief enable I2C DMA mode + \brief configure I2C DMA mode \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] dmastate: only one parameter can be selected which is shown as below: - \arg I2C_DMA_ON: DMA mode enable - \arg I2C_DMA_OFF: DMA mode disable + \arg I2C_DMA_ON: enable DMA mode + \arg I2C_DMA_OFF: disable DMA mode \param[out] none \retval none */ -void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate) { /* configure I2C DMA function */ uint32_t ctl = 0U; - + ctl = I2C_CTL1(i2c_periph); - ctl &= ~(I2C_CTL1_DMAON); + ctl &= ~(I2C_CTL1_DMAON); ctl |= dmastate; I2C_CTL1(i2c_periph) = ctl; } /*! - \brief configure whether next DMA EOT is DMA last transfer or not + \brief configure whether next DMA EOT is DMA last transfer or not \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] dmalast: only one parameter can be selected which is shown as below: @@ -379,36 +379,36 @@ void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast) { /* configure DMA last transfer */ uint32_t ctl = 0U; - + ctl = I2C_CTL1(i2c_periph); - ctl &= ~(I2C_CTL1_DMALST); + ctl &= ~(I2C_CTL1_DMALST); ctl |= dmalast; I2C_CTL1(i2c_periph) = ctl; } /*! - \brief whether to stretch SCL low when data is not ready in slave mode + \brief whether to stretch SCL low when data is not ready in slave mode \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] stretchpara: only one parameter can be selected which is shown as below: - \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled - \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \arg I2C_SCLSTRETCH_ENABLE: enable SCL stretching + \arg I2C_SCLSTRETCH_DISABLE: disable SCL stretching \param[out] none \retval none */ void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) { - /* configure I2C SCL strerching enable or disable */ + /* configure I2C SCL strerching */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); - ctl &= ~(I2C_CTL0_SS); + ctl &= ~(I2C_CTL0_SS); ctl |= stretchpara; I2C_CTL0(i2c_periph) = ctl; } /*! - \brief whether or not to response to a general call + \brief whether or not to response to a general call \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] gcallpara: only one parameter can be selected which is shown as below: @@ -421,15 +421,15 @@ void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) { /* configure slave response to a general call enable or disable */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); - ctl &= ~(I2C_CTL0_GCEN); + ctl &= ~(I2C_CTL0_GCEN); ctl |= gcallpara; I2C_CTL0(i2c_periph) = ctl; } /*! - \brief software reset I2C + \brief configure software reset of I2C \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] sreset: only one parameter can be selected which is shown as below: @@ -442,28 +442,28 @@ void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) { /* modify CTL0 and configure software reset I2C state */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); - ctl &= ~(I2C_CTL0_SRESET); + ctl &= ~(I2C_CTL0_SRESET); ctl |= sreset; I2C_CTL0(i2c_periph) = ctl; } /*! - \brief I2C PEC calculation on or off + \brief configure I2C PEC calculation \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] pecstate: only one parameter can be selected which is shown as below: - \arg I2C_PEC_ENABLE: PEC calculation on - \arg I2C_PEC_DISABLE: PEC calculation off + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off \param[out] none \retval none */ -void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate) { /* on/off PEC calculation */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); ctl &= ~(I2C_CTL0_PECEN); ctl |= pecstate; @@ -471,20 +471,20 @@ void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) } /*! - \brief I2C whether to transfer PEC value + \brief configure whether to transfer PEC value \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] pecpara: only one parameter can be selected which is shown as below: - \arg I2C_PECTRANS_ENABLE: transfer PEC - \arg I2C_PECTRANS_DISABLE: not transfer PEC + \arg I2C_PECTRANS_ENABLE: transfer PEC value + \arg I2C_PECTRANS_DISABLE: not transfer PEC value \param[out] none \retval none */ -void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara) { /* whether to transfer PEC */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); ctl &= ~(I2C_CTL0_PECTRANS); ctl |= pecpara; @@ -492,31 +492,31 @@ void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) } /*! - \brief get packet error checking value + \brief get packet error checking value \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval PEC value */ uint8_t i2c_pec_value_get(uint32_t i2c_periph) { - return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV)>>STAT1_PECV_OFFSET); + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV) >> STAT1_PECV_OFFSET); } /*! - \brief I2C issue alert through SMBA pin + \brief configure I2C alert through SMBA pin \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] smbuspara: only one parameter can be selected which is shown as below: - \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin - \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin \param[out] none \retval none */ -void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara) { - /* issue alert through SMBA pin configure*/ + /* configure smubus alert through SMBA pin */ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); ctl &= ~(I2C_CTL0_SALT); ctl |= smbuspara; @@ -524,7 +524,7 @@ void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) } /*! - \brief enable or disable I2C ARP protocol in SMBus switch + \brief configure I2C ARP protocol in SMBus \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] arpstate: only one parameter can be selected which is shown as below: @@ -533,11 +533,11 @@ void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) \param[out] none \retval none */ -void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) +void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate) { /* enable or disable I2C ARP protocol*/ uint32_t ctl = 0U; - + ctl = I2C_CTL0(i2c_periph); ctl &= ~(I2C_CTL0_ARPEN); ctl |= arpstate; @@ -545,105 +545,122 @@ void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) } /*! - \brief analog noise filter disable + \brief disable analog noise filter \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_analog_noise_filter_disable(uint32_t i2c_periph) { - I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD; + I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD; } /*! - \brief analog noise filter enable + \brief enable analog noise filter \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_analog_noise_filter_enable(uint32_t i2c_periph) { - I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD); + I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD); } /*! - \brief digital noise filter configuration + \brief configure digital noise filter \param[in] i2c_periph: I2Cx(x=0,1,2) - \param[in] dfilterpara: refer to enum i2c_digital_filter_enum + \param[in] dfilterpara: refer to i2c_digital_filter_enum + only one parameter can be selected which is shown as below: + \arg I2C_DF_DISABLE: disable digital noise filter + \arg I2C_DF_1PCLK: enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 + \arg I2C_DF_2PCLK: enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 + \arg I2C_DF_3PCLK: enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 + \arg I2C_DF_4PCLK: enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 + \arg I2C_DF_5PCLK: enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 + \arg I2C_DF_6PCLK: enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 + \arg I2C_DF_7PCLK: enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 + \arg I2C_DF_8PCLK: enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 + \arg I2C_DF_9PCLK: enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 + \arg I2C_DF_10PCLK: enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 + \arg I2C_DF_11CLK: enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 + \arg I2C_DF_12CLK: enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 + \arg I2C_DF_13PCLK: enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 + \arg I2C_DF_14PCLK: enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 + \arg I2C_DF_15PCLK: enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 \param[out] none \retval none */ -void i2c_digital_noise_filter_config(uint32_t i2c_periph,i2c_digital_filter_enum dfilterpara) +void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara) { - I2C_FCTL(i2c_periph) |= dfilterpara; + I2C_FCTL(i2c_periph) |= dfilterpara; } /*! - \brief enable SAM_V interface + \brief enable SAM_V interface \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_sam_enable(uint32_t i2c_periph) { - I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; } /*! - \brief disable SAM_V interface + \brief disable SAM_V interface \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_sam_disable(uint32_t i2c_periph) { - I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); } /*! - \brief enable SAM_V interface timeout detect + \brief enable SAM_V interface timeout detect \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_sam_timeout_enable(uint32_t i2c_periph) { - I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; } /*! - \brief disable SAM_V interface timeout detect + \brief disable SAM_V interface timeout detect \param[in] i2c_periph: I2Cx(x=0,1,2) \param[out] none \retval none */ void i2c_sam_timeout_disable(uint32_t i2c_periph) { - I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); } /*! - \brief check I2C flag is set or not + \brief get I2C flag status \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] flag: I2C flags, refer to i2c_flag_enum only one parameter can be selected which is shown as below: - \arg I2C_FLAG_SBSEND: start condition send out + \arg I2C_FLAG_SBSEND: start condition sent out in master mode \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode \arg I2C_FLAG_BTC: byte transmission finishes \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode \arg I2C_FLAG_STPDET: stop condition detected in slave mode - \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_FLAG_RBNE: I2C_DATA is not empty during receiving \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus \arg I2C_FLAG_LOSTARB: arbitration lost in master mode \arg I2C_FLAG_AERR: acknowledge error - \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode \arg I2C_FLAG_PECERR: PEC error when receiving data \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode \arg I2C_FLAG_SMBALT: SMBus alert status \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode \arg I2C_FLAG_I2CBSY: busy flag - \arg I2C_FLAG_TRS: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver \arg I2C_FLAG_RXGC: general call address (00h) received \arg I2C_FLAG_DEFSMB: default address of SMBus device \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode @@ -657,26 +674,26 @@ void i2c_sam_timeout_disable(uint32_t i2c_periph) */ FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) { - if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){ + if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear I2C flag + \brief clear I2C flag status \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] flag: I2C flags, refer to i2c_flag_enum only one parameter can be selected which is shown as below: - \arg I2C_FLAG_SMBALT: SMBus Alert status + \arg I2C_FLAG_SMBALT: SMBus alert status \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode \arg I2C_FLAG_PECERR: PEC error when receiving data \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode \arg I2C_FLAG_AERR: acknowledge error - \arg I2C_FLAG_LOSTARB: arbitration lost in master mode - \arg I2C_FLAG_BERR: a bus error - \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode \arg I2C_FLAG_TFF: txframe fall flag \arg I2C_FLAG_TFR: txframe rise flag \arg I2C_FLAG_RFF: rxframe fall flag @@ -686,27 +703,27 @@ FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) */ void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag) { - if(I2C_FLAG_ADDSEND == flag){ + if(I2C_FLAG_ADDSEND == flag) { /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ I2C_STAT0(i2c_periph); I2C_STAT1(i2c_periph); - }else{ + } else { I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag)); } } /*! - \brief enable I2C interrupt + \brief enable I2C interrupt \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum only one parameter can be selected which is shown as below: - \arg I2C_INT_ERR: error interrupt enable - \arg I2C_INT_EV: event interrupt enable - \arg I2C_INT_BUF: buffer interrupt enable - \arg I2C_INT_TFF: txframe fall interrupt enable - \arg I2C_INT_TFR: txframe rise interrupt enable - \arg I2C_INT_RFF: rxframe fall interrupt enable - \arg I2C_INT_RFR: rxframe rise interrupt enable + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_EV: event interrupt + \arg I2C_INT_BUF: buffer interrupt + \arg I2C_INT_TFF: txframe fall interrupt + \arg I2C_INT_TFR: txframe rise interrupt + \arg I2C_INT_RFF: rxframe fall interrupt + \arg I2C_INT_RFR: rxframe rise interrupt \param[out] none \retval none */ @@ -716,17 +733,17 @@ void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) } /*! - \brief disable I2C interrupt + \brief disable I2C interrupt \param[in] i2c_periph: I2Cx(x=0,1,2) - \param[in] interrupt: I2C interrupts, refer to i2c_flag_enum + \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum only one parameter can be selected which is shown as below: - \arg I2C_INT_ERR: error interrupt enable - \arg I2C_INT_EV: event interrupt enable - \arg I2C_INT_BUF: buffer interrupt enable - \arg I2C_INT_TFF: txframe fall interrupt enable - \arg I2C_INT_TFR: txframe rise interrupt enable - \arg I2C_INT_RFF: rxframe fall interrupt enable - \arg I2C_INT_RFR: rxframe rise interrupt enable + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_EV: event interrupt + \arg I2C_INT_BUF: buffer interrupt + \arg I2C_INT_TFF: txframe fall interrupt + \arg I2C_INT_TFR: txframe rise interrupt + \arg I2C_INT_RFF: rxframe fall interrupt + \arg I2C_INT_RFR: rxframe rise interrupt \param[out] none \retval none */ @@ -736,15 +753,15 @@ void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) } /*! - \brief check I2C interrupt flag + \brief get I2C interrupt flag status \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum only one parameter can be selected which is shown as below: \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag - \arg I2C_INT_FLAG_BTC: byte transmission finishes + \arg I2C_INT_FLAG_BTC: byte transmission finishes interrupt flag \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag - \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag @@ -753,7 +770,7 @@ void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag - \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag @@ -764,31 +781,31 @@ void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) { uint32_t intenable = 0U, flagstatus = 0U, bufie; - + /* check BUFIE */ bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; - + /* get the interrupt enable bit status */ intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); /* get the corresponding flag bit status */ flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); - if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){ - if(intenable && bufie){ - intenable = 1U; - }else{ + if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)) { + if(intenable && bufie) { + intenable = 1U; + } else { intenable = 0U; } } - if((0U != flagstatus) && (0U != intenable)){ + if((0U != flagstatus) && (0U != intenable)) { return SET; - }else{ - return RESET; + } else { + return RESET; } } /*! - \brief clear I2C interrupt flag + \brief clear I2C interrupt flag status \param[in] i2c_periph: I2Cx(x=0,1,2) \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum only one parameter can be selected which is shown as below: @@ -799,7 +816,7 @@ FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum i \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag - \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag @@ -809,11 +826,11 @@ FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum i */ void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) { - if(I2C_INT_FLAG_ADDSEND == int_flag){ + if(I2C_INT_FLAG_ADDSEND == int_flag) { /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ I2C_STAT0(i2c_periph); I2C_STAT1(i2c_periph); - }else{ + } else { I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag)); } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c index cd5a752..64c6f36 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_ipa.c \brief IPA driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -130,8 +128,8 @@ void ipa_background_lut_loading_enable(void) \brief set pixel format convert mode, the function is invalid when the IPA transfer is enabled \param[in] pfcm: pixel format convert mode only one parameter can be selected which is shown as below: - \arg IPA_FGTODE: foreground memory to destination memory without pixel format convert - \arg IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert + \arg IPA_FGTODE: foreground memory to destination memory without pixel format convert + \arg IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert \arg IPA_FGBGTODE: blending foreground and background memory to destination memory \arg IPA_FILL_UP_DE: fill up destination memory with specific color \param[out] none @@ -144,23 +142,23 @@ void ipa_pixel_format_convert_mode_set(uint32_t pfcm) } /*! - \brief initialize the structure of IPA foreground parameter struct with the default values, it is + \brief initialize the structure of IPA foreground parameter struct with the default values, it is suggested that call this function after an ipa_foreground_parameter_struct structure is defined \param[in] none \param[out] foreground_struct: the data needed to initialize foreground foreground_memaddr: foreground memory base address foreground_lineoff: foreground line offset - foreground_prealpha: foreground pre-defined alpha value + foreground_prealpha: foreground pre-defined alpha value foreground_alpha_algorithm: IPA_FG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2 foreground_pf: foreground pixel format(FOREGROUND_PPF_ARGB8888,FOREGROUND_PPF_RGB888,FOREGROUND_PPF_RGB565, FOREGROUND_PPF_ARG1555,FOREGROUND_PPF_ARGB4444,FOREGROUND_PPF_L8,FOREGROUND_PPF_AL44, FOREGROUND_PPF_AL88,FOREGROUND_PPF_L4,FOREGROUND_PPF_A8,FOREGROUND_PPF_A4) foreground_prered: foreground pre-defined red value - foreground_pregreen: foreground pre-defined green value + foreground_pregreen: foreground pre-defined green value foreground_preblue: foreground pre-defined blue value \retval none */ -void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct* foreground_struct) +void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct *foreground_struct) { /* initialize the struct parameters with default values */ foreground_struct->foreground_memaddr = IPA_DEFAULT_VALUE; @@ -189,15 +187,15 @@ void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct* foreground \param[out] none \retval none */ -void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct) +void ipa_foreground_init(ipa_foreground_parameter_struct *foreground_struct) { FlagStatus tempflag = RESET; - if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + if(RESET != (IPA_CTL & IPA_CTL_TEN)) { tempflag = SET; /* reset the TEN in order to configure the following bits */ IPA_CTL &= ~IPA_CTL_TEN; } - + /* foreground memory base address configuration */ IPA_FMADDR &= ~(IPA_FMADDR_FMADDR); IPA_FMADDR = foreground_struct->foreground_memaddr; @@ -205,23 +203,23 @@ void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct) IPA_FLOFF &= ~(IPA_FLOFF_FLOFF); IPA_FLOFF = foreground_struct->foreground_lineoff; /* foreground pixel format pre-defined alpha, alpha calculation algorithm configuration */ - IPA_FPCTL &= ~(IPA_FPCTL_FPDAV|IPA_FPCTL_FAVCA|IPA_FPCTL_FPF); - IPA_FPCTL |= (foreground_struct->foreground_prealpha<<24U); + IPA_FPCTL &= ~(IPA_FPCTL_FPDAV | IPA_FPCTL_FAVCA | IPA_FPCTL_FPF); + IPA_FPCTL |= (foreground_struct->foreground_prealpha << 24U); IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm; IPA_FPCTL |= foreground_struct->foreground_pf; /* foreground pre-defined red green blue configuration */ - IPA_FPV &= ~(IPA_FPV_FPDRV|IPA_FPV_FPDGV|IPA_FPV_FPDBV); - IPA_FPV |= ((foreground_struct->foreground_prered<<16U)|(foreground_struct->foreground_pregreen<<8U) - |(foreground_struct->foreground_preblue)); - - if(SET == tempflag){ + IPA_FPV &= ~(IPA_FPV_FPDRV | IPA_FPV_FPDGV | IPA_FPV_FPDBV); + IPA_FPV |= ((foreground_struct->foreground_prered << 16U) | (foreground_struct->foreground_pregreen << 8U) + | (foreground_struct->foreground_preblue)); + + if(SET == tempflag) { /* restore the state of TEN */ IPA_CTL |= IPA_CTL_TEN; } } /*! - \brief initialize the structure of IPA background parameter struct with the default values, it is + \brief initialize the structure of IPA background parameter struct with the default values, it is suggested that call this function after an ipa_background_parameter_struct structure is defined \param[in] none \param[out] background_struct: the data needed to initialize background @@ -237,7 +235,7 @@ void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct) background_preblue: background pre-defined blue value \retval none */ -void ipa_background_struct_para_init(ipa_background_parameter_struct* background_struct) +void ipa_background_struct_para_init(ipa_background_parameter_struct *background_struct) { /* initialize the struct parameters with default values */ background_struct->background_memaddr = IPA_DEFAULT_VALUE; @@ -266,15 +264,15 @@ void ipa_background_struct_para_init(ipa_background_parameter_struct* background \param[out] none \retval none */ -void ipa_background_init(ipa_background_parameter_struct* background_struct) +void ipa_background_init(ipa_background_parameter_struct *background_struct) { FlagStatus tempflag = RESET; - if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + if(RESET != (IPA_CTL & IPA_CTL_TEN)) { tempflag = SET; /* reset the TEN in order to configure the following bits */ IPA_CTL &= ~IPA_CTL_TEN; } - + /* background memory base address configuration */ IPA_BMADDR &= ~(IPA_BMADDR_BMADDR); IPA_BMADDR = background_struct->background_memaddr; @@ -282,23 +280,23 @@ void ipa_background_init(ipa_background_parameter_struct* background_struct) IPA_BLOFF &= ~(IPA_BLOFF_BLOFF); IPA_BLOFF = background_struct->background_lineoff; /* background pixel format pre-defined alpha, alpha calculation algorithm configuration */ - IPA_BPCTL &= ~(IPA_BPCTL_BPDAV|IPA_BPCTL_BAVCA|IPA_BPCTL_BPF); - IPA_BPCTL |= (background_struct->background_prealpha<<24U); + IPA_BPCTL &= ~(IPA_BPCTL_BPDAV | IPA_BPCTL_BAVCA | IPA_BPCTL_BPF); + IPA_BPCTL |= (background_struct->background_prealpha << 24U); IPA_BPCTL |= background_struct->background_alpha_algorithm; - IPA_BPCTL |= background_struct->background_pf; + IPA_BPCTL |= background_struct->background_pf; /* background pre-defined red green blue configuration */ - IPA_BPV &= ~(IPA_BPV_BPDRV|IPA_BPV_BPDGV|IPA_BPV_BPDBV); - IPA_BPV |= ((background_struct->background_prered<<16U)|(background_struct->background_pregreen<<8U) - |(background_struct->background_preblue)); - - if(SET == tempflag){ + IPA_BPV &= ~(IPA_BPV_BPDRV | IPA_BPV_BPDGV | IPA_BPV_BPDBV); + IPA_BPV |= ((background_struct->background_prered << 16U) | (background_struct->background_pregreen << 8U) + | (background_struct->background_preblue)); + + if(SET == tempflag) { /* restore the state of TEN */ IPA_CTL |= IPA_CTL_TEN; } } /*! - \brief initialize the structure of IPA destination parameter struct with the default values, it is + \brief initialize the structure of IPA destination parameter struct with the default values, it is suggested that call this function after an ipa_destination_parameter_struct structure is defined \param[in] none \param[out] destination_struct: the data needed to initialize destination parameter @@ -314,7 +312,7 @@ void ipa_background_init(ipa_background_parameter_struct* background_struct) image_height: height of the image to be processed \retval none */ -void ipa_destination_struct_para_init(ipa_destination_parameter_struct* destination_struct) +void ipa_destination_struct_para_init(ipa_destination_parameter_struct *destination_struct) { /* initialize the struct parameters with default values */ destination_struct->destination_pf = IPA_DPF_ARGB8888; @@ -344,53 +342,53 @@ void ipa_destination_struct_para_init(ipa_destination_parameter_struct* destinat \param[out] none \retval none */ -void ipa_destination_init(ipa_destination_parameter_struct* destination_struct) +void ipa_destination_init(ipa_destination_parameter_struct *destination_struct) { uint32_t destination_pixelformat; FlagStatus tempflag = RESET; - if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + if(RESET != (IPA_CTL & IPA_CTL_TEN)) { tempflag = SET; /* reset the TEN in order to configure the following bits */ IPA_CTL &= ~IPA_CTL_TEN; } - + /* destination pixel format configuration */ IPA_DPCTL &= ~(IPA_DPCTL_DPF); IPA_DPCTL = destination_struct->destination_pf; destination_pixelformat = destination_struct->destination_pf; /* destination pixel format ARGB8888 */ - switch(destination_pixelformat){ + switch(destination_pixelformat) { case IPA_DPF_ARGB8888: - IPA_DPV &= ~(IPA_DPV_DPDBV_0|(IPA_DPV_DPDGV_0)|(IPA_DPV_DPDRV_0)|(IPA_DPV_DPDAV_0)); - IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U) - |(destination_struct->destination_prered<<16U) - |(destination_struct->destination_prealpha<<24U)); + IPA_DPV &= ~(IPA_DPV_DPDBV_0 | (IPA_DPV_DPDGV_0) | (IPA_DPV_DPDRV_0) | (IPA_DPV_DPDAV_0)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U) + | (destination_struct->destination_prered << 16U) + | (destination_struct->destination_prealpha << 24U)); break; /* destination pixel format RGB888 */ case IPA_DPF_RGB888: - IPA_DPV &= ~(IPA_DPV_DPDBV_1|(IPA_DPV_DPDGV_1)|(IPA_DPV_DPDRV_1)); - IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<8U) - |(destination_struct->destination_prered<<16U)); + IPA_DPV &= ~(IPA_DPV_DPDBV_1 | (IPA_DPV_DPDGV_1) | (IPA_DPV_DPDRV_1)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U) + | (destination_struct->destination_prered << 16U)); break; /* destination pixel format RGB565 */ case IPA_DPF_RGB565: - IPA_DPV &= ~(IPA_DPV_DPDBV_2|(IPA_DPV_DPDGV_2)|(IPA_DPV_DPDRV_2)); - IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U) - |(destination_struct->destination_prered<<11U)); + IPA_DPV &= ~(IPA_DPV_DPDBV_2 | (IPA_DPV_DPDGV_2) | (IPA_DPV_DPDRV_2)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U) + | (destination_struct->destination_prered << 11U)); break; /* destination pixel format ARGB1555 */ case IPA_DPF_ARGB1555: - IPA_DPV &= ~(IPA_DPV_DPDBV_3|(IPA_DPV_DPDGV_3)|(IPA_DPV_DPDRV_3)|(IPA_DPV_DPDAV_3)); - IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<5U) - |(destination_struct->destination_prered<<10U) - |(destination_struct->destination_prealpha<<15U)); + IPA_DPV &= ~(IPA_DPV_DPDBV_3 | (IPA_DPV_DPDGV_3) | (IPA_DPV_DPDRV_3) | (IPA_DPV_DPDAV_3)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U) + | (destination_struct->destination_prered << 10U) + | (destination_struct->destination_prealpha << 15U)); break; /* destination pixel format ARGB4444 */ case IPA_DPF_ARGB4444: - IPA_DPV &= ~(IPA_DPV_DPDBV_4|(IPA_DPV_DPDGV_4)|(IPA_DPV_DPDRV_4)|(IPA_DPV_DPDAV_4)); - IPA_DPV = (destination_struct->destination_preblue|(destination_struct->destination_pregreen<<4U) - |(destination_struct->destination_prered<<8U) - |(destination_struct->destination_prealpha<<12U)); + IPA_DPV &= ~(IPA_DPV_DPDBV_4 | (IPA_DPV_DPDGV_4) | (IPA_DPV_DPDRV_4) | (IPA_DPV_DPDAV_4)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 4U) + | (destination_struct->destination_prered << 8U) + | (destination_struct->destination_prealpha << 12U)); break; default: break; @@ -400,12 +398,12 @@ void ipa_destination_init(ipa_destination_parameter_struct* destination_struct) IPA_DMADDR = destination_struct->destination_memaddr; /* destination line offset configuration */ IPA_DLOFF &= ~(IPA_DLOFF_DLOFF); - IPA_DLOFF =destination_struct->destination_lineoff; + IPA_DLOFF = destination_struct->destination_lineoff; /* image size configuration */ - IPA_IMS &= ~(IPA_IMS_HEIGHT|IPA_IMS_WIDTH); - IPA_IMS |= ((destination_struct->image_width<<16U)|(destination_struct->image_height)); - - if(SET == tempflag){ + IPA_IMS &= ~(IPA_IMS_HEIGHT | IPA_IMS_WIDTH); + IPA_IMS |= ((destination_struct->image_width << 16U) | (destination_struct->image_height)); + + if(SET == tempflag) { /* restore the state of TEN */ IPA_CTL |= IPA_CTL_TEN; } @@ -422,25 +420,25 @@ void ipa_destination_init(ipa_destination_parameter_struct* destination_struct) void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_lut_addr) { FlagStatus tempflag = RESET; - if(RESET != (IPA_FPCTL & IPA_FPCTL_FLLEN)){ + if(RESET != (IPA_FPCTL & IPA_FPCTL_FLLEN)) { tempflag = SET; /* reset the FLLEN in order to configure the following bits */ IPA_FPCTL &= ~IPA_FPCTL_FLLEN; } - + /* foreground LUT number of pixel configuration */ - IPA_FPCTL |= ((uint32_t)fg_lut_num<<8U); + IPA_FPCTL |= ((uint32_t)fg_lut_num << 8U); /* foreground LUT pixel format configuration */ - if(IPA_LUT_PF_RGB888 == fg_lut_pf){ + if(IPA_LUT_PF_RGB888 == fg_lut_pf) { IPA_FPCTL |= IPA_FPCTL_FLPF; - }else{ + } else { IPA_FPCTL &= ~(IPA_FPCTL_FLPF); } /* foreground LUT memory base address configuration */ IPA_FLMADDR &= ~(IPA_FLMADDR_FLMADDR); IPA_FLMADDR = fg_lut_addr; - - if(SET == tempflag){ + + if(SET == tempflag) { /* restore the state of FLLEN */ IPA_FPCTL |= IPA_FPCTL_FLLEN; } @@ -457,25 +455,25 @@ void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_ void ipa_background_lut_init(uint8_t bg_lut_num, uint8_t bg_lut_pf, uint32_t bg_lut_addr) { FlagStatus tempflag = RESET; - if(RESET != (IPA_BPCTL & IPA_BPCTL_BLLEN)){ + if(RESET != (IPA_BPCTL & IPA_BPCTL_BLLEN)) { tempflag = SET; /* reset the BLLEN in order to configure the following bits */ IPA_BPCTL &= ~IPA_BPCTL_BLLEN; } - + /* background LUT number of pixel configuration */ - IPA_BPCTL |= ((uint32_t)bg_lut_num<<8U); + IPA_BPCTL |= ((uint32_t)bg_lut_num << 8U); /* background LUT pixel format configuration */ - if(IPA_LUT_PF_RGB888 == bg_lut_pf){ + if(IPA_LUT_PF_RGB888 == bg_lut_pf) { IPA_BPCTL |= IPA_BPCTL_BLPF; - }else{ + } else { IPA_BPCTL &= ~(IPA_BPCTL_BLPF); } /* background LUT memory base address configuration */ IPA_BLMADDR &= ~(IPA_BLMADDR_BLMADDR); IPA_BLMADDR = bg_lut_addr; - - if(SET == tempflag){ + + if(SET == tempflag) { /* restore the state of BLLEN */ IPA_BPCTL |= IPA_BPCTL_BLLEN; } @@ -501,9 +499,9 @@ void ipa_line_mark_config(uint16_t line_num) */ void ipa_inter_timer_config(uint8_t timer_cfg) { - if(IPA_INTER_TIMER_ENABLE == timer_cfg){ + if(IPA_INTER_TIMER_ENABLE == timer_cfg) { IPA_ITCTL |= IPA_ITCTL_ITEN; - }else{ + } else { IPA_ITCTL &= ~(IPA_ITCTL_ITEN); } } @@ -518,7 +516,7 @@ void ipa_interval_clock_num_config(uint8_t clk_num) { /* NCCI[7:0] bits have no meaning if ITEN is '0' */ IPA_ITCTL &= ~(IPA_ITCTL_NCCI); - IPA_ITCTL |= ((uint32_t)clk_num<<8U); + IPA_ITCTL |= ((uint32_t)clk_num << 8U); } /*! @@ -536,9 +534,9 @@ void ipa_interval_clock_num_config(uint8_t clk_num) */ FlagStatus ipa_flag_get(uint32_t flag) { - if(RESET != (IPA_INTF & flag)){ + if(RESET != (IPA_INTF & flag)) { return SET; - }else{ + } else { return RESET; } } @@ -612,9 +610,9 @@ void ipa_interrupt_disable(uint32_t int_flag) */ FlagStatus ipa_interrupt_flag_get(uint32_t int_flag) { - if(0U != (IPA_INTF & int_flag)){ + if(0U != (IPA_INTF & int_flag)) { return SET; - }else{ + } else { return RESET; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c index a1a8b6c..63f76a1 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c @@ -2,42 +2,40 @@ \file gd32f4xx_iref.c \brief IREF driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_iref.h" /*! - \brief deinit IREF + \brief deinitialize IREF \param[in] none \param[out] none \retval none @@ -60,7 +58,7 @@ void iref_enable(void) } /*! - \brief disable IREF + \brief disable IREF \param[in] none \param[out] none \retval none @@ -71,7 +69,7 @@ void iref_disable(void) } /*! - \brief set IREF mode + \brief set IREF mode \param[in] step \arg IREF_MODE_LOW_POWER: 1uA step \arg IREF_MODE_HIGH_CURRENT: 8uA step @@ -85,7 +83,7 @@ void iref_mode_set(uint32_t step) } /*! - \brief set IREF precision_trim_value + \brief set IREF precision_trim_value \param[in] precisiontrim \arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)% \param[out] none @@ -98,7 +96,7 @@ void iref_precision_trim_value_set(uint32_t precisiontrim) } /*! - \brief set IREF sink mode + \brief set IREF sink mode \param[in] sinkmode \arg IREF_SOURCE_CURRENT : source current. \arg IREF_SINK_CURRENT: sink current @@ -112,7 +110,7 @@ void iref_sink_set(uint32_t sinkmode) } /*! - \brief set IREF step data + \brief set IREF step data \param[in] stepdata \arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x \param[out] none diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c index 2cf04fb..63a7572 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c @@ -1,37 +1,33 @@ /*! \file gd32f4xx_misc.c \brief MISC driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx - \version 2021-12-09, V2.1.1, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -62,34 +58,34 @@ void nvic_priority_group_set(uint32_t nvic_prigroup) \param[out] none \retval none */ -void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority) { uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U; /* use the priority group value to get the temp_pre and the temp_sub */ - if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE0_SUB4){ - temp_pre=0U; - temp_sub=0x4U; - }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE1_SUB3){ - temp_pre=1U; - temp_sub=0x3U; - }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE2_SUB2){ - temp_pre=2U; - temp_sub=0x2U; - }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE3_SUB1){ - temp_pre=3U; - temp_sub=0x1U; - }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE4_SUB0){ - temp_pre=4U; - temp_sub=0x0U; - }else{ + if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE0_SUB4) { + temp_pre = 0U; + temp_sub = 0x4U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE1_SUB3) { + temp_pre = 1U; + temp_sub = 0x3U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE2_SUB2) { + temp_pre = 2U; + temp_sub = 0x2U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE3_SUB1) { + temp_pre = 3U; + temp_sub = 0x1U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE4_SUB0) { + temp_pre = 4U; + temp_sub = 0x0U; + } else { nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); - temp_pre=2U; - temp_sub=0x2U; + temp_pre = 2U; + temp_sub = 0x2U; } /* get the temp_priority to fill the NVIC->IP register */ temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); - temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub)); + temp_priority |= nvic_irq_sub_priority & (0x0FU >> (0x4U - temp_sub)); temp_priority = temp_priority << 0x04U; NVIC->IP[nvic_irq] = (uint8_t)temp_priority; /* enable the selected IRQ */ @@ -126,10 +122,10 @@ void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) /*! \brief set the state of the low power mode \param[in] lowpower_mode: the low power mode state - \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power mode by exiting from ISR \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode - \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up by all the enable and disable interrupts \param[out] none \retval none @@ -142,10 +138,10 @@ void system_lowpower_set(uint8_t lowpower_mode) /*! \brief reset the state of the low power mode \param[in] lowpower_mode: the low power mode state - \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power mode by exiting from ISR \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode - \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be woke up by the enable interrupts \param[out] none \retval none @@ -166,10 +162,10 @@ void system_lowpower_reset(uint8_t lowpower_mode) void systick_clksource_set(uint32_t systick_clksource) { - if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource) { /* set the systick clock source from HCLK */ SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; - }else{ + } else { /* set the systick clock source from HCLK/8 */ SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c index f71bfed..df389f4 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c @@ -2,42 +2,41 @@ \file gd32f4xx_pmu.c \brief PMU driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_pmu.h" #include "core_cm4.h" + /*! - \brief reset PMU register + \brief reset PMU registers \param[in] none \param[out] none \retval none @@ -50,7 +49,7 @@ void pmu_deinit(void) } /*! - \brief select low voltage detector threshold + \brief select low voltage detector threshold \param[in] lvdt_n: \arg PMU_LVDT_0: voltage threshold is 2.1V \arg PMU_LVDT_1: voltage threshold is 2.3V @@ -76,7 +75,19 @@ void pmu_lvd_select(uint32_t lvdt_n) } /*! - \brief select LDO output voltage + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief select LDO output voltage this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL \param[in] ldo_output: \arg PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode @@ -92,21 +103,30 @@ void pmu_ldo_output_select(uint32_t ldo_output) } /*! - \brief enable low-driver mode in deep-sleep mode - \param[in] lowdr_mode: - \arg PMU_LOWDRIVER_ENABLE: enable low-driver mode in deep-sleep mode - \arg PMU_LOWDRIVER_DISABLE: disable low-driver mode in deep-sleep mode + \brief enable high-driver mode + this bit set by software only when IRC16M or HXTAL used as system clock + \param[in] none \param[out] none \retval none */ -void pmu_low_driver_mode_enable(uint32_t lowdr_mode) +void pmu_highdriver_mode_enable(void) { - PMU_CTL &= ~PMU_CTL_LDEN; - PMU_CTL |= lowdr_mode; + PMU_CTL |= PMU_CTL_HDEN; } /*! - \brief switch high-driver mode + \brief disable high-driver mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_highdriver_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_HDEN; +} + +/*! + \brief switch high-driver mode this bit set by software only when IRC16M or HXTAL used as system clock \param[in] highdr_switch: \arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch @@ -117,77 +137,64 @@ void pmu_low_driver_mode_enable(uint32_t lowdr_mode) void pmu_highdriver_switch_select(uint32_t highdr_switch) { /* wait for HDRF flag set */ - while(SET != pmu_flag_get(PMU_FLAG_HDRF)){ + while(SET != pmu_flag_get(PMU_FLAG_HDRF)) { } PMU_CTL &= ~PMU_CTL_HDS; PMU_CTL |= highdr_switch; } /*! - \brief enable high-driver mode - this bit set by software only when IRC16M or HXTAL used as system clock + \brief enable low-driver mode in deep-sleep \param[in] none \param[out] none \retval none */ -void pmu_highdriver_mode_enable(void) +void pmu_lowdriver_mode_enable(void) { - PMU_CTL |= PMU_CTL_HDEN; + PMU_CTL |= PMU_CTL_LDEN; } /*! - \brief disable high-driver mode + \brief disable low-driver mode in deep-sleep \param[in] none \param[out] none \retval none */ -void pmu_highdriver_mode_disable(void) +void pmu_lowdriver_mode_disable(void) { - PMU_CTL &= ~PMU_CTL_HDEN; -} - -/*! - \brief disable PMU lvd - \param[in] none - \param[out] none - \retval none -*/ -void pmu_lvd_disable(void) -{ - /* disable LVD */ - PMU_CTL &= ~PMU_CTL_LVDEN; + PMU_CTL &= ~PMU_CTL_LDEN; } /*! - \brief low-driver mode when use low power LDO + \brief in deep-sleep mode, driver mode when use low power LDO \param[in] mode: \arg PMU_NORMALDR_LOWPWR: normal driver when use low power LDO \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO \param[out] none \retval none */ -void pmu_lowdriver_lowpower_config(uint32_t mode) +void pmu_lowpower_driver_config(uint32_t mode) { PMU_CTL &= ~PMU_CTL_LDLP; PMU_CTL |= mode; } /*! - \brief low-driver mode when use normal power LDO + \brief in deep-sleep mode, driver mode when use normal power LDO \param[in] mode: \arg PMU_NORMALDR_NORMALPWR: normal driver when use normal power LDO \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use normal power LDO \param[out] none \retval none */ -void pmu_lowdriver_normalpower_config(uint32_t mode) +void pmu_normalpower_driver_config(uint32_t mode) { PMU_CTL &= ~PMU_CTL_LDNP; PMU_CTL |= mode; } /*! - \brief PMU work at sleep mode + \brief PMU work in sleep mode \param[in] sleepmodecmd: \arg WFI_CMD: use WFI command \arg WFE_CMD: use WFE command @@ -198,157 +205,142 @@ void pmu_to_sleepmode(uint8_t sleepmodecmd) { /* clear sleepdeep bit of Cortex-M4 system control register */ SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); - + /* select WFI or WFE command to enter sleep mode */ - if(WFI_CMD == sleepmodecmd){ + if(WFI_CMD == sleepmodecmd) { __WFI(); - }else{ + } else { __WFE(); } } /*! - \brief PMU work at deepsleep mode + \brief PMU work in deep-sleep mode \param[in] ldo - \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode - \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode - \param[in] deepsleepmodecmd: + \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deep-sleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deep-sleep mode + \param[in] lowdrive: + only one parameter can be selected which is shown as below: + \arg PMU_LOWDRIVER_DISABLE: Low-driver mode disable in deep-sleep mode + \arg PMU_LOWDRIVER_ENABLE: Low-driver mode enable in deep-sleep mode + \param[in] deepsleepmodecmd: \arg WFI_CMD: use WFI command \arg WFE_CMD: use WFE command \param[out] none \retval none */ -void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd) +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd) { - static uint32_t reg_snap[ 4 ]; + static uint32_t reg_snap[4]; /* clear stbmod and ldolp bits */ - PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); - + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP | PMU_CTL_LDEN | PMU_CTL_LDNP | PMU_CTL_LDLP)); + /* set ldolp bit according to pmu_ldo */ PMU_CTL |= ldo; - + + /* configure low drive mode in deep-sleep mode */ + if(PMU_LOWDRIVER_ENABLE == lowdrive) { + if(PMU_LDO_NORMAL == ldo) { + PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDNP); + } else { + PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDLP); + } + } /* set sleepdeep bit of Cortex-M4 system control register */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - reg_snap[ 0 ] = REG32( 0xE000E010U ); - reg_snap[ 1 ] = REG32( 0xE000E100U ); - reg_snap[ 2 ] = REG32( 0xE000E104U ); - reg_snap[ 3 ] = REG32( 0xE000E108U ); - - REG32( 0xE000E010U ) &= 0x00010004U; - REG32( 0xE000E180U ) = 0XFF7FF831U; - REG32( 0xE000E184U ) = 0XBFFFF8FFU; - REG32( 0xE000E188U ) = 0xFFFFEFFFU; - - /* select WFI or WFE command to enter deepsleep mode */ - if(WFI_CMD == deepsleepmodecmd){ + reg_snap[0] = REG32(0xE000E010U); + reg_snap[1] = REG32(0xE000E100U); + reg_snap[2] = REG32(0xE000E104U); + reg_snap[3] = REG32(0xE000E108U); + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0XFF7FF831U; + REG32(0xE000E184U) = 0XBFFFF8FFU; + REG32(0xE000E188U) = 0xFFFFEFFFU; + + /* select WFI or WFE command to enter deep-sleep mode */ + if(WFI_CMD == deepsleepmodecmd) { __WFI(); - }else{ + } else { __SEV(); __WFE(); __WFE(); } - - REG32( 0xE000E010U ) = reg_snap[ 0 ] ; - REG32( 0xE000E100U ) = reg_snap[ 1 ] ; - REG32( 0xE000E104U ) = reg_snap[ 2 ] ; - REG32( 0xE000E108U ) = reg_snap[ 3 ] ; - + + REG32(0xE000E010U) = reg_snap[0]; + REG32(0xE000E100U) = reg_snap[1]; + REG32(0xE000E104U) = reg_snap[2]; + REG32(0xE000E108U) = reg_snap[3]; + /* reset sleepdeep bit of Cortex-M4 system control register */ SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); } /*! - \brief pmu work at standby mode - \param[in] standbymodecmd: - \arg WFI_CMD: use WFI command - \arg WFE_CMD: use WFE command + \brief pmu work in standby mode + \param[in] none \param[out] none \retval none */ -void pmu_to_standbymode(uint8_t standbymodecmd) +void pmu_to_standbymode(void) { - /* set sleepdeep bit of Cortex-M4 system control register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - /* set stbmod bit */ PMU_CTL |= PMU_CTL_STBMOD; - + /* reset wakeup flag */ PMU_CTL |= PMU_CTL_WURST; - - /* select WFI or WFE command to enter standby mode */ - if(WFI_CMD == standbymodecmd){ - __WFI(); - }else{ - __WFE(); - __WFE(); - } + + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0XFFFFFFF7U; + REG32(0xE000E184U) = 0XFFFFFDFFU; + REG32(0xE000E188U) = 0xFFFFFFFFU; + + /* select WFI command to enter standby mode */ + __WFI(); } /*! - \brief backup SRAM LDO on - \param[in] bkp_ldo: - \arg PMU_BLDOON_OFF: backup SRAM LDO closed - \arg PMU_BLDOON_ON: open the backup SRAM LDO + \brief enable PMU wakeup pin + \param[in] none \param[out] none \retval none */ -void pmu_backup_ldo_config(uint32_t bkp_ldo) +void pmu_wakeup_pin_enable(void) { - PMU_CS &= ~PMU_CS_BLDOON; - PMU_CS |= bkp_ldo; + PMU_CS |= PMU_CS_WUPEN; } /*! - \brief reset flag bit - \param[in] flag_reset: - \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag - \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \brief disable PMU wakeup pin + \param[in] none \param[out] none \retval none */ -void pmu_flag_reset(uint32_t flag_reset) +void pmu_wakeup_pin_disable(void) { - switch(flag_reset){ - case PMU_FLAG_RESET_WAKEUP: - /* reset wakeup flag */ - PMU_CTL |= PMU_CTL_WURST; - break; - case PMU_FLAG_RESET_STANDBY: - /* reset standby flag */ - PMU_CTL |= PMU_CTL_STBRST; - break; - default : - break; - } + PMU_CS &= ~PMU_CS_WUPEN; } /*! - \brief get flag state - \param[in] pmu_flag: - \arg PMU_FLAG_WAKEUP: wakeup flag - \arg PMU_FLAG_STANDBY: standby flag - \arg PMU_FLAG_LVD: lvd flag - \arg PMU_FLAG_BLDORF: backup SRAM LDO ready flag - \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag - \arg PMU_FLAG_HDRF: high-driver ready flag - \arg PMU_FLAG_HDSRF: high-driver switch ready flag - \arg PMU_FLAG_LDRF: low-driver mode ready flag + \brief backup SRAM LDO on + \param[in] bkp_ldo: + \arg PMU_BLDOON_OFF: backup SRAM LDO closed + \arg PMU_BLDOON_ON: open the backup SRAM LDO \param[out] none - \retval FlagStatus: SET or RESET + \retval none */ -FlagStatus pmu_flag_get(uint32_t pmu_flag) +void pmu_backup_ldo_config(uint32_t bkp_ldo) { - if(PMU_CS & pmu_flag){ - return SET; - }else{ - return RESET; - } + PMU_CS &= ~PMU_CS_BLDOON; + PMU_CS |= bkp_ldo; } /*! - \brief enable backup domain write + \brief enable write access to the registers in backup domain \param[in] none \param[out] none \retval none @@ -359,7 +351,7 @@ void pmu_backup_write_enable(void) } /*! - \brief disable backup domain write + \brief disable write access to the registers in backup domain \param[in] none \param[out] none \retval none @@ -370,23 +362,48 @@ void pmu_backup_write_disable(void) } /*! - \brief enable wakeup pin - \param[in] none + \brief get flag state + \param[in] flag: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \arg PMU_FLAG_BLDORF: backup SRAM LDO ready flag + \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag + \arg PMU_FLAG_HDRF: high-driver ready flag + \arg PMU_FLAG_HDSRF: high-driver switch ready flag + \arg PMU_FLAG_LDRF: low-driver mode ready flag \param[out] none - \retval none + \retval FlagStatus: SET or RESET */ -void pmu_wakeup_pin_enable(void) +FlagStatus pmu_flag_get(uint32_t flag) { - PMU_CS |= PMU_CS_WUPEN; + if(PMU_CS & flag) { + return SET; + } else { + return RESET; + } } /*! - \brief disable wakeup pin - \param[in] none + \brief clear flag bit + \param[in] flag: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag \param[out] none \retval none */ -void pmu_wakeup_pin_disable(void) +void pmu_flag_clear(uint32_t flag) { - PMU_CS &= ~PMU_CS_WUPEN; + switch(flag) { + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c index 215d631..5c99285 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_rcu.c \brief RCU driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -60,9 +58,9 @@ void rcu_deinit(void) RCU_CTL |= RCU_CTL_IRC16MEN; rcu_osci_stab_wait(RCU_IRC16M); RCU_CFG0 &= ~RCU_CFG0_SCS; - - /* reset CTL register */ - RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN | RCU_CTL_PLLI2SEN + + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN | RCU_CTL_PLLI2SEN | RCU_CTL_PLLSAIEN); RCU_CTL &= ~(RCU_CTL_HXTALBPS); /* reset CFG0 register */ @@ -78,14 +76,14 @@ void rcu_deinit(void) /* reset INT register */ RCU_INT = 0x00000000U; /* reset CFG1 register */ - RCU_CFG1 &= ~(RCU_CFG1_PLLSAIRDIV | RCU_CFG1_TIMERSEL); + RCU_CFG1 &= ~(RCU_CFG1_PLLSAIRDIV | RCU_CFG1_TIMERSEL); } /*! \brief enable the peripherals clock \param[in] periph: RCU peripherals, refer to rcu_periph_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_GPIOx (x = A, B, C, D, E, F, G, H, I): GPIO ports clock \arg RCU_CRC: CRC clock \arg RCU_BKPSRAM: BKPSRAM clock \arg RCU_TCMSRAM: TCMSRAM clock @@ -101,17 +99,17 @@ void rcu_deinit(void) \arg RCU_TRNG: TRNG clock \arg RCU_USBFS: USBFS clock \arg RCU_EXMC: EXMC clock - \arg RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_TIMERx (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock \arg RCU_WWDGT: WWDGT clock - \arg RCU_SPIx (x=0,1,2,3,4,5): SPI clock - \arg RCU_USARTx (x=0,1,2,5): USART clock - \arg RCU_UARTx (x=3,4,6,7): UART clock - \arg RCU_I2Cx (x=0,1,2): I2C clock - \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_SPIx (x = 0, 1, 2, 3, 4, 5): SPI clock + \arg RCU_USARTx (x = 0, 1, 2, 5): USART clock + \arg RCU_UARTx (x = 3, 4, 6, 7): UART clock + \arg RCU_I2Cx (x = 0, 1, 2): I2C clock + \arg RCU_CANx (x = 0, 1): CAN clock \arg RCU_PMU: PMU clock \arg RCU_DAC: DAC clock \arg RCU_RTC: RTC clock - \arg RCU_ADCx (x=0,1,2): ADC clock + \arg RCU_ADCx (x = 0, 1, 2): ADC clock \arg RCU_SDIO: SDIO clock \arg RCU_SYSCFG: SYSCFG clock \arg RCU_TLI: TLI clock @@ -129,7 +127,7 @@ void rcu_periph_clock_enable(rcu_periph_enum periph) \brief disable the peripherals clock \param[in] periph: RCU peripherals, refer to rcu_periph_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOx (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_GPIOx (x = A, B, C, D, E, F, G, H, I): GPIO ports clock \arg RCU_CRC: CRC clock \arg RCU_BKPSRAM: BKPSRAM clock \arg RCU_TCMSRAM: TCMSRAM clock @@ -145,17 +143,17 @@ void rcu_periph_clock_enable(rcu_periph_enum periph) \arg RCU_TRNG: TRNG clock \arg RCU_USBFS: USBFS clock \arg RCU_EXMC: EXMC clock - \arg RCU_TIMERx (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_TIMERx (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock \arg RCU_WWDGT: WWDGT clock - \arg RCU_SPIx (x=0,1,2,3,4,5): SPI clock - \arg RCU_USARTx (x=0,1,2,5): USART clock - \arg RCU_UARTx (x=3,4,6,7): UART clock - \arg RCU_I2Cx (x=0,1,2): I2C clock - \arg RCU_CANx (x=0,1): CAN clock + \arg RCU_SPIx (x = 0, 1, 2, 3, 4, 5): SPI clock + \arg RCU_USARTx (x = 0, 1, 2, 5): USART clock + \arg RCU_UARTx (x = 3, 4, 6, 7): UART clock + \arg RCU_I2Cx (x = 0, 1, 2): I2C clock + \arg RCU_CANx (x = 0, 1): CAN clock \arg RCU_PMU: PMU clock \arg RCU_DAC: DAC clock \arg RCU_RTC: RTC clock - \arg RCU_ADCx (x=0,1,2): ADC clock + \arg RCU_ADCx (x = 0, 1, 2): ADC clock \arg RCU_SDIO: SDIO clock \arg RCU_SYSCFG: SYSCFG clock \arg RCU_TLI: TLI clock @@ -173,7 +171,7 @@ void rcu_periph_clock_disable(rcu_periph_enum periph) \brief enable the peripherals clock when sleep mode \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_GPIOx_SLP (x = A, B, C, D, E, F, G, H, I): GPIO ports clock \arg RCU_CRC_SLP: CRC clock \arg RCU_FMC_SLP: FMC clock \arg RCU_SRAM0_SLP: SRAM0 clock @@ -192,17 +190,17 @@ void rcu_periph_clock_disable(rcu_periph_enum periph) \arg RCU_TRNG_SLP: TRNG clock \arg RCU_USBFS_SLP: USBFS clock \arg RCU_EXMC_SLP: EXMC clock - \arg RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_TIMERx_SLP (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock \arg RCU_WWDGT_SLP: WWDGT clock - \arg RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock - \arg RCU_USARTx_SLP (x=0,1,2,5): USART clock - \arg RCU_UARTx_SLP (x=3,4,6,7): UART clock - \arg RCU_I2Cx_SLP (x=0,1,2): I2C clock - \arg RCU_CANx_SLP (x=0,1): CAN clock + \arg RCU_SPIx_SLP (x = 0, 1, 2, 3, 4, 5): SPI clock + \arg RCU_USARTx_SLP (x = 0, 1, 2, 5): USART clock + \arg RCU_UARTx_SLP (x = 3, 4, 6, 7): UART clock + \arg RCU_I2Cx_SLP (x = 0, 1, 2): I2C clock + \arg RCU_CANx_SLP (x = 0, 1): CAN clock \arg RCU_PMU_SLP: PMU clock \arg RCU_DAC_SLP: DAC clock \arg RCU_RTC_SLP: RTC clock - \arg RCU_ADCx_SLP (x=0,1,2): ADC clock + \arg RCU_ADCx_SLP (x = 0, 1, 2): ADC clock \arg RCU_SDIO_SLP: SDIO clock \arg RCU_SYSCFG_SLP: SYSCFG clock \arg RCU_TLI_SLP: TLI clock @@ -220,7 +218,7 @@ void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) \brief disable the peripherals clock when sleep mode \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOx_SLP (x=A,B,C,D,E,F,G,H,I): GPIO ports clock + \arg RCU_GPIOx_SLP (x = A, B, C, D, E, F, G, H, I): GPIO ports clock \arg RCU_CRC_SLP: CRC clock \arg RCU_FMC_SLP: FMC clock \arg RCU_SRAM0_SLP: SRAM0 clock @@ -239,17 +237,17 @@ void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) \arg RCU_TRNG_SLP: TRNG clock \arg RCU_USBFS_SLP: USBFS clock \arg RCU_EXMC_SLP: EXMC clock - \arg RCU_TIMERx_SLP (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): TIMER clock + \arg RCU_TIMERx_SLP (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock \arg RCU_WWDGT_SLP: WWDGT clock - \arg RCU_SPIx_SLP (x=0,1,2,3,4,5): SPI clock - \arg RCU_USARTx_SLP (x=0,1,2,5): USART clock - \arg RCU_UARTx_SLP (x=3,4,6,7): UART clock - \arg RCU_I2Cx_SLP (x=0,1,2): I2C clock - \arg RCU_CANx_SLP (x=0,1): CAN clock + \arg RCU_SPIx_SLP (x = 0, 1, 2, 3, 4, 5): SPI clock + \arg RCU_USARTx_SLP (x = 0, 1, 2, 5): USART clock + \arg RCU_UARTx_SLP (x = 3, 4, 6, 7): UART clock + \arg RCU_I2Cx_SLP (x = 0, 1, 2): I2C clock + \arg RCU_CANx_SLP (x = 0, 1): CAN clock \arg RCU_PMU_SLP: PMU clock \arg RCU_DAC_SLP: DAC clock \arg RCU_RTC_SLP: RTC clock - \arg RCU_ADCx_SLP (x=0,1,2): ADC clock + \arg RCU_ADCx_SLP (x = 0, 1, 2): ADC clock \arg RCU_SDIO_SLP: SDIO clock \arg RCU_SYSCFG_SLP: SYSCFG clock \arg RCU_TLI_SLP: TLI clock @@ -267,7 +265,7 @@ void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) \brief reset the peripherals \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports + \arg RCU_GPIOxRST (x = A, B, C, D, E, F, G, H, I): reset GPIO ports \arg RCU_CRCRST: reset CRC \arg RCU_DMAxRST (x=0,1): reset DMA \arg RCU_IPARST: reset IPA @@ -277,16 +275,16 @@ void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) \arg RCU_TRNGRST: reset TRNG \arg RCU_USBFSRST: reset USBFS \arg RCU_EXMCRST: reset EXMC - \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER + \arg RCU_TIMERxRST (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): reset TIMER \arg RCU_WWDGTRST: reset WWDGT - \arg RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI - \arg RCU_USARTxRST (x=0,1,2,5): reset USART - \arg RCU_UARTxRST (x=3,4,6,7): reset UART - \arg RCU_I2CxRST (x=0,1,2): reset I2C - \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_SPIxRST (x = 0, 1, 2, 3, 4, 5): reset SPI + \arg RCU_USARTxRST (x = 0, 1, 2, 5): reset USART + \arg RCU_UARTxRST (x = 3, 4, 6, 7): reset UART + \arg RCU_I2CxRST (x = 0, 1, 2): reset I2C + \arg RCU_CANxRST (x = 0, 1): reset CAN \arg RCU_PMURST: reset PMU \arg RCU_DACRST: reset DAC - \arg RCU_ADCRST (x=0,1,2): reset ADC + \arg RCU_ADCRST (x = 0, 1, 2): reset ADC \arg RCU_SDIORST: reset SDIO \arg RCU_SYSCFGRST: reset SYSCFG \arg RCU_TLIRST: reset TLI @@ -304,7 +302,7 @@ void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) \brief disable reset the peripheral \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum only one parameter can be selected which is shown as below: - \arg RCU_GPIOxRST (x=A,B,C,D,E,F,G,H,I): reset GPIO ports + \arg RCU_GPIOxRST (x = A, B, C, D, E, F, G, H, I): reset GPIO ports \arg RCU_CRCRST: reset CRC \arg RCU_DMAxRST (x=0,1): reset DMA \arg RCU_IPARST: reset IPA @@ -314,16 +312,16 @@ void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) \arg RCU_TRNGRST: reset TRNG \arg RCU_USBFSRST: reset USBFS \arg RCU_EXMCRST: reset EXMC - \arg RCU_TIMERxRST (x=0,1,2,3,4,5,6,7,8,9,10,11,12,13): reset TIMER + \arg RCU_TIMERxRST (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): reset TIMER \arg RCU_WWDGTRST: reset WWDGT - \arg RCU_SPIxRST (x=0,1,2,3,4,5): reset SPI - \arg RCU_USARTxRST (x=0,1,2,5): reset USART - \arg RCU_UARTxRST (x=3,4,6,7): reset UART - \arg RCU_I2CxRST (x=0,1,2): reset I2C - \arg RCU_CANxRST (x=0,1): reset CAN + \arg RCU_SPIxRST (x = 0, 1, 2, 3, 4, 5): reset SPI + \arg RCU_USARTxRST (x = 0, 1, 2, 5): reset USART + \arg RCU_UARTxRST (x = 3, 4, 6, 7): reset UART + \arg RCU_I2CxRST (x = 0, 1, 2): reset I2C + \arg RCU_CANxRST (x = 0, 1): reset CAN \arg RCU_PMURST: reset PMU \arg RCU_DACRST: reset DAC - \arg RCU_ADCRST (x=0,1,2): reset ADC + \arg RCU_ADCRST (x = 0, 1, 2): reset ADC \arg RCU_SDIORST: reset SDIO \arg RCU_SYSCFGRST: reset SYSCFG \arg RCU_TLIRST: reset TLI @@ -372,7 +370,7 @@ void rcu_bkp_reset_disable(void) void rcu_system_clock_source_config(uint32_t ck_sys) { uint32_t reg; - + reg = RCU_CFG0; /* reset the SCS bits and set according to ck_sys */ reg &= ~RCU_CFG0_SCS; @@ -397,14 +395,14 @@ uint32_t rcu_system_clock_source_get(void) \brief configure the AHB clock prescaler selection \param[in] ck_ahb: AHB clock prescaler selection only one parameter can be selected which is shown as below: - \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \arg RCU_AHB_CKSYS_DIVx (x = 1, 2, 4, 8, 16, 64, 128, 256, 512): select CK_SYS / x as CK_AHB \param[out] none \retval none */ void rcu_ahb_clock_config(uint32_t ck_ahb) { uint32_t reg; - + reg = RCU_CFG0; /* reset the AHBPSC bits and set according to ck_ahb */ reg &= ~RCU_CFG0_AHBPSC; @@ -416,17 +414,17 @@ void rcu_ahb_clock_config(uint32_t ck_ahb) \param[in] ck_apb1: APB1 clock prescaler selection only one parameter can be selected which is shown as below: \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 - \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 - \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 - \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 - \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB / 2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB / 4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB / 8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB / 16 as CK_APB1 \param[out] none \retval none */ void rcu_apb1_clock_config(uint32_t ck_apb1) { uint32_t reg; - + reg = RCU_CFG0; /* reset the APB1PSC and set according to ck_apb1 */ reg &= ~RCU_CFG0_APB1PSC; @@ -438,17 +436,17 @@ void rcu_apb1_clock_config(uint32_t ck_apb1) \param[in] ck_apb2: APB2 clock prescaler selection only one parameter can be selected which is shown as below: \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 - \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 - \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 - \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 - \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB / 2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB / 4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB / 8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB / 16 as CK_APB2 \param[out] none \retval none */ void rcu_apb2_clock_config(uint32_t ck_apb2) { uint32_t reg; - + reg = RCU_CFG0; /* reset the APB2PSC and set according to ck_apb2 */ reg &= ~RCU_CFG0_APB2PSC; @@ -463,18 +461,18 @@ void rcu_apb2_clock_config(uint32_t ck_apb2) \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected \arg RCU_CKOUT0SRC_PLLP: PLLP selected - \param[in] ckout0_div: CK_OUT0 divider - \arg RCU_CKOUT0_DIVx(x=1,2,3,4,5): CK_OUT0 is divided by x + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x = 1, 2, 3, 4, 5): CK_OUT0 is divided by x \param[out] none \retval none */ void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) { uint32_t reg; - + reg = RCU_CFG0; /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */ - reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV ); + reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV); RCU_CFG0 = (reg | ckout0_src | ckout0_div); } @@ -485,16 +483,16 @@ void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) \arg RCU_CKOUT1SRC_SYSTEMCLOCK: system clock selected \arg RCU_CKOUT1SRC_PLLI2SR: PLLI2SR selected \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected - \arg RCU_CKOUT1SRC_PLLP: PLLP selected - \param[in] ckout1_div: CK_OUT1 divider - \arg RCU_CKOUT1_DIVx(x=1,2,3,4,5): CK_OUT1 is divided by x + \arg RCU_CKOUT1SRC_PLLP: PLLP selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx(x = 1, 2, 3, 4, 5): CK_OUT1 is divided by x \param[out] none \retval none */ void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) { uint32_t reg; - + reg = RCU_CFG0; /* reset the CKOUT1SRC, CKOUT1DIV and set according to ckout1_src and ckout1_div */ reg &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV); @@ -502,7 +500,7 @@ void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) } /*! - \brief configure the main PLL clock + \brief configure the main PLL clock \param[in] pll_src: PLL clock source selection \arg RCU_PLLSRC_IRC16M: select IRC16M as PLL source clock \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock @@ -521,35 +519,35 @@ ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uin { uint32_t ss_modulation_inc; uint32_t ss_modulation_reg; - + ss_modulation_inc = 0U; ss_modulation_reg = RCU_PLLSSCTL; /* calculate the minimum factor of PLLN */ - if((ss_modulation_reg & RCU_PLLSSCTL_SSCGON) == RCU_PLLSSCTL_SSCGON){ - if((ss_modulation_reg & RCU_SS_TYPE_DOWN) == RCU_SS_TYPE_DOWN){ + if((ss_modulation_reg & RCU_PLLSSCTL_SSCGON) == RCU_PLLSSCTL_SSCGON) { + if((ss_modulation_reg & RCU_SS_TYPE_DOWN) == RCU_SS_TYPE_DOWN) { ss_modulation_inc += RCU_SS_MODULATION_DOWN_INC; - }else{ + } else { ss_modulation_inc += RCU_SS_MODULATION_CENTER_INC; } } - + /* check the function parameter */ - if(CHECK_PLL_PSC_VALID(pll_psc) && CHECK_PLL_N_VALID(pll_n,ss_modulation_inc) && - CHECK_PLL_P_VALID(pll_p) && CHECK_PLL_Q_VALID(pll_q)){ - RCU_PLL = pll_psc | (pll_n << 6) | (((pll_p >> 1) - 1U) << 16) | - (pll_src) | (pll_q << 24); - }else{ + if(CHECK_PLL_PSC_VALID(pll_psc) && CHECK_PLL_N_VALID(pll_n, ss_modulation_inc) && + CHECK_PLL_P_VALID(pll_p) && CHECK_PLL_Q_VALID(pll_q)) { + RCU_PLL = pll_psc | (pll_n << 6) | (((pll_p >> 1) - 1U) << 16) | + (pll_src) | (pll_q << 24); + } else { /* return status */ return ERROR; } - + /* return status */ return SUCCESS; } /*! - \brief configure the PLLI2S clock + \brief configure the PLLI2S clock \param[in] plli2s_n: the PLLI2S VCO clock multi factor \arg this parameter should be selected between 50 and 500 \param[in] plli2s_r: the PLLI2S R output frequency division factor from PLLI2S VCO clock @@ -560,19 +558,19 @@ ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uin ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_r) { /* check the function parameter */ - if(CHECK_PLLI2S_N_VALID(plli2s_n) && CHECK_PLLI2S_R_VALID(plli2s_r)){ + if(CHECK_PLLI2S_N_VALID(plli2s_n) && CHECK_PLLI2S_R_VALID(plli2s_r)) { RCU_PLLI2S = (plli2s_n << 6) | (plli2s_r << 28); - }else{ + } else { /* return status */ return ERROR; } - + /* return status */ - return SUCCESS; + return SUCCESS; } /*! - \brief configure the PLLSAI clock + \brief configure the PLLSAI clock \param[in] pllsai_n: the PLLSAI VCO clock multi factor \arg this parameter should be selected between 50 and 500 \param[in] pllsai_p: the PLLSAI P output frequency division factor from PLL VCO clock @@ -585,13 +583,13 @@ ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_r) ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_r) { /* check the function parameter */ - if(CHECK_PLLSAI_N_VALID(pllsai_n) && CHECK_PLLSAI_P_VALID(pllsai_p) && CHECK_PLLSAI_R_VALID(pllsai_r)){ + if(CHECK_PLLSAI_N_VALID(pllsai_n) && CHECK_PLLSAI_P_VALID(pllsai_p) && CHECK_PLLSAI_R_VALID(pllsai_r)) { RCU_PLLSAI = (pllsai_n << 6U) | (((pllsai_p >> 1U) - 1U) << 16U) | (pllsai_r << 28U); - }else{ + } else { /* return status */ return ERROR; } - + /* return status */ return SUCCESS; } @@ -603,34 +601,34 @@ ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsa \arg RCU_RTCSRC_NONE: no clock selected \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock \arg RCU_RTCSRC_IRC32K: CK_IRC32K selected as RTC source clock - \arg RCU_RTCSRC_HXTAL_DIV_RTCDIV: CK_HXTAL/RTCDIV selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV_RTCDIV: CK_HXTAL / RTCDIV selected as RTC source clock \param[out] none \retval none */ void rcu_rtc_clock_config(uint32_t rtc_clock_source) { uint32_t reg; - - reg = RCU_BDCTL; + + reg = RCU_BDCTL; /* reset the RTCSRC bits and set according to rtc_clock_source */ reg &= ~RCU_BDCTL_RTCSRC; RCU_BDCTL = (reg | rtc_clock_source); } /*! - \brief configure the frequency division of RTC clock when HXTAL was selected as its clock source + \brief configure the frequency division of RTC clock when HXTAL was selected as its clock source \param[in] rtc_div: RTC clock frequency division only one parameter can be selected which is shown as below: \arg RCU_RTC_HXTAL_NONE: no clock for RTC - \arg RCU_RTC_HXTAL_DIVx: RTCDIV clock select CK_HXTAL/x, x = 2....31 + \arg RCU_RTC_HXTAL_DIVx: RTCDIV clock select CK_HXTAL / x, x = 2....31 \param[out] none \retval none */ void rcu_rtc_div_config(uint32_t rtc_div) { uint32_t reg; - - reg = RCU_CFG0; + + reg = RCU_CFG0; /* reset the RTCDIV bits and set according to rtc_div value */ reg &= ~RCU_CFG0_RTCDIV; RCU_CFG0 = (reg | rtc_div); @@ -649,8 +647,8 @@ void rcu_rtc_div_config(uint32_t rtc_div) void rcu_i2s_clock_config(uint32_t i2s_clock_source) { uint32_t reg; - - reg = RCU_CFG0; + + reg = RCU_CFG0; /* reset the I2SSEL bit and set according to i2s_clock_source */ reg &= ~RCU_CFG0_I2SSEL; RCU_CFG0 = (reg | i2s_clock_source); @@ -668,7 +666,7 @@ void rcu_i2s_clock_config(uint32_t i2s_clock_source) void rcu_ck48m_clock_config(uint32_t ck48m_clock_source) { uint32_t reg; - + reg = RCU_ADDCTL; /* reset the CK48MSEL bit and set according to i2s_clock_source */ reg &= ~RCU_ADDCTL_CK48MSEL; @@ -687,7 +685,7 @@ void rcu_ck48m_clock_config(uint32_t ck48m_clock_source) void rcu_pll48m_clock_config(uint32_t pll48m_clock_source) { uint32_t reg; - + reg = RCU_ADDCTL; /* reset the PLL48MSEL bit and set according to pll48m_clock_source */ reg &= ~RCU_ADDCTL_PLL48MSEL; @@ -698,13 +696,13 @@ void rcu_pll48m_clock_config(uint32_t pll48m_clock_source) \brief configure the TIMER clock prescaler selection \param[in] timer_clock_prescaler: TIMER clock selection only one parameter can be selected which is shown as below: - \arg RCU_TIMER_PSC_MUL2: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) + \arg RCU_TIMER_PSC_MUL2: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). - or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; + or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) - \arg RCU_TIMER_PSC_MUL4: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), - 0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). - or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; + \arg RCU_TIMER_PSC_MUL4: if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), + 0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) \param[out] none \retval none @@ -712,9 +710,9 @@ void rcu_pll48m_clock_config(uint32_t pll48m_clock_source) void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler) { /* configure the TIMERSEL bit and select the TIMER clock prescaler */ - if(timer_clock_prescaler == RCU_TIMER_PSC_MUL2){ + if(timer_clock_prescaler == RCU_TIMER_PSC_MUL2) { RCU_CFG1 &= timer_clock_prescaler; - }else{ + } else { RCU_CFG1 |= timer_clock_prescaler; } } @@ -730,144 +728,13 @@ void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler) void rcu_tli_clock_div_config(uint32_t pllsai_r_div) { uint32_t reg; - + reg = RCU_CFG1; /* reset the PLLSAIRDIV bit and set according to pllsai_r_div */ reg &= ~RCU_CFG1_PLLSAIRDIV; RCU_CFG1 = (reg | pllsai_r_div); } -/*! - \brief get the clock stabilization and periphral reset flags - \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum - only one parameter can be selected which is shown as below: - \arg RCU_FLAG_IRC16MSTB: IRC16M stabilization flag - \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag - \arg RCU_FLAG_PLLSTB: PLL stabilization flag - \arg RCU_FLAG_PLLI2SSTB: PLLI2S stabilization flag - \arg RCU_FLAG_PLLSAISTB: PLLSAI stabilization flag - \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag - \arg RCU_FLAG_IRC32KSTB: IRC32K stabilization flag - \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag - \arg RCU_FLAG_BORRST: BOR reset flags - \arg RCU_FLAG_EPRST: external PIN reset flag - \arg RCU_FLAG_PORRST: Power reset flag - \arg RCU_FLAG_SWRST: software reset flag - \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag - \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag - \arg RCU_FLAG_LPRST: low-power reset flag - \param[out] none - \retval none -*/ -FlagStatus rcu_flag_get(rcu_flag_enum flag) -{ - /* get the rcu flag */ - if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ - return SET; - }else{ - return RESET; - } -} - -/*! - \brief clear all the reset flag - \param[in] none - \param[out] none - \retval none -*/ -void rcu_all_reset_flag_clear(void) -{ - RCU_RSTSCK |= RCU_RSTSCK_RSTFC; -} - -/*! - \brief get the clock stabilization interrupt and ckm flags - \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum - only one parameter can be selected which is shown as below: - \arg RCU_INT_FLAG_IRC32KSTB: IRC32K stabilization interrupt flag - \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag - \arg RCU_INT_FLAG_IRC16MSTB: IRC16M stabilization interrupt flag - \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag - \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag - \arg RCU_INT_FLAG_PLLI2SSTB: PLLI2S stabilization interrupt flag - \arg RCU_INT_FLAG_PLLSAISTB: PLLSAI stabilization interrupt flag - \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag - \arg RCU_INT_FLAG_IRC48MSTB: IRC48M stabilization interrupt flag - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) -{ - /* get the rcu interrupt flag */ - if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){ - return SET; - }else{ - return RESET; - } -} - -/*! - \brief clear the interrupt flags - \param[in] int_flag: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum - only one parameter can be selected which is shown as below: - \arg RCU_INT_FLAG_IRC32KSTB_CLR: IRC32K stabilization interrupt flag clear - \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear - \arg RCU_INT_FLAG_IRC16MSTB_CLR: IRC16M stabilization interrupt flag clear - \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear - \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear - \arg RCU_INT_FLAG_PLLI2SSTB_CLR: PLLI2S stabilization interrupt flag clear - \arg RCU_INT_FLAG_PLLSAISTB_CLR: PLLSAI stabilization interrupt flag clear - \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear - \arg RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear - \param[out] none - \retval none -*/ -void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag) -{ - RCU_REG_VAL(int_flag) |= BIT(RCU_BIT_POS(int_flag)); -} - -/*! - \brief enable the stabilization interrupt - \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum - Only one parameter can be selected which is shown as below: - \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt enable - \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable - \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt enable - \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable - \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable - \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt enable - \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt enable - \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable - \param[out] none - \retval none -*/ -void rcu_interrupt_enable(rcu_int_enum interrupt) -{ - RCU_REG_VAL(interrupt) |= BIT(RCU_BIT_POS(interrupt)); -} - - -/*! - \brief disable the stabilization interrupt - \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum - only one parameter can be selected which is shown as below: - \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt disable - \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable - \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt disable - \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable - \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable - \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt disable - \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt disable - \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt disable - \param[out] none - \retval none -*/ -void rcu_interrupt_disable(rcu_int_enum interrupt) -{ - RCU_REG_VAL(interrupt) &= ~BIT(RCU_BIT_POS(interrupt)); -} - /*! \brief configure the LXTAL drive capability \param[in] lxtal_dricap: drive capability of LXTAL @@ -880,9 +747,9 @@ void rcu_interrupt_disable(rcu_int_enum interrupt) void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) { uint32_t reg; - + reg = RCU_BDCTL; - + /* reset the LXTALDRI bits and set according to lxtal_dricap */ reg &= ~RCU_BDCTL_LXTALDRI; RCU_BDCTL = (reg | lxtal_dricap); @@ -908,109 +775,109 @@ ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) uint32_t stb_cnt = 0U; ErrStatus reval = ERROR; FlagStatus osci_stat = RESET; - - switch(osci){ + + switch(osci) { /* wait HXTAL stable */ case RCU_HXTAL: - while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)) { reval = SUCCESS; } break; /* wait LXTAL stable */ case RCU_LXTAL: - while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)) { reval = SUCCESS; } break; - /* wait IRC16M stable */ + /* wait IRC16M stable */ case RCU_IRC16M: - while((RESET == osci_stat) && (IRC16M_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (IRC16M_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_IRC16MSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_IRC16MSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_IRC16MSTB)) { reval = SUCCESS; } break; - /* wait IRC48M stable */ + /* wait IRC48M stable */ case RCU_IRC48M: - while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB); stb_cnt++; } - + /* check whether flag is set */ - if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)) { reval = SUCCESS; } break; /* wait IRC32K stable */ case RCU_IRC32K: - while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_IRC32KSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)) { reval = SUCCESS; } break; - /* wait PLL stable */ + /* wait PLL stable */ case RCU_PLL_CK: - while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)) { reval = SUCCESS; } break; /* wait PLLI2S stable */ case RCU_PLLI2S_CK: - while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_PLLI2SSTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_PLLI2SSTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_PLLI2SSTB)) { reval = SUCCESS; } break; - /* wait PLLSAI stable */ + /* wait PLLSAI stable */ case RCU_PLLSAI_CK: - while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { osci_stat = rcu_flag_get(RCU_FLAG_PLLSAISTB); stb_cnt++; } - + /* check whether flag is set */ - if(RESET != rcu_flag_get(RCU_FLAG_PLLSAISTB)){ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSAISTB)) { reval = SUCCESS; } break; - + default: break; } - + /* return value */ return reval; } @@ -1068,8 +935,8 @@ void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) { uint32_t reg; - switch(osci){ - /* enable HXTAL to bypass mode */ + switch(osci) { + /* enable HXTAL to bypass mode */ case RCU_HXTAL: reg = RCU_CTL; RCU_CTL &= ~RCU_CTL_HXTALEN; @@ -1086,7 +953,7 @@ void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) case RCU_IRC32K: case RCU_PLL_CK: case RCU_PLLI2S_CK: - case RCU_PLLSAI_CK: + case RCU_PLLSAI_CK: break; default: break; @@ -1105,9 +972,9 @@ void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) { uint32_t reg; - - switch(osci){ - /* disable HXTAL to bypass mode */ + + switch(osci) { + /* disable HXTAL to bypass mode */ case RCU_HXTAL: reg = RCU_CTL; RCU_CTL &= ~RCU_CTL_HXTALEN; @@ -1124,36 +991,13 @@ void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) case RCU_IRC32K: case RCU_PLL_CK: case RCU_PLLI2S_CK: - case RCU_PLLSAI_CK: + case RCU_PLLSAI_CK: break; default: break; } } -/*! - \brief enable the HXTAL clock monitor - \param[in] none - \param[out] none - \retval none -*/ - -void rcu_hxtal_clock_monitor_enable(void) -{ - RCU_CTL |= RCU_CTL_CKMEN; -} - -/*! - \brief disable the HXTAL clock monitor - \param[in] none - \param[out] none - \retval none -*/ -void rcu_hxtal_clock_monitor_disable(void) -{ - RCU_CTL &= ~RCU_CTL_CKMEN; -} - /*! \brief set the IRC16M adjust value \param[in] irc16m_adjval: IRC16M adjust value, must be between 0 and 0x1F @@ -1164,41 +1008,13 @@ void rcu_hxtal_clock_monitor_disable(void) void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval) { uint32_t reg; - + reg = RCU_CTL; /* reset the IRC16MADJ bits and set according to irc16m_adjval */ reg &= ~RCU_CTL_IRC16MADJ; RCU_CTL = (reg | ((irc16m_adjval & RCU_IRC16M_ADJUST_MASK) << RCU_IRC16M_ADJUST_OFFSET)); } -/*! - \brief unlock the voltage key - \param[in] none - \param[out] none - \retval none -*/ -void rcu_voltage_key_unlock(void) -{ - RCU_VKEY = RCU_VKEY_UNLOCK; -} - -/*! - \brief deep-sleep mode voltage select - \param[in] dsvol: deep sleep mode voltage - only one parameter can be selected which is shown as below: - \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V - \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V - \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V - \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V - \param[out] none - \retval none -*/ -void rcu_deepsleep_voltage_set(uint32_t dsvol) -{ - dsvol &= RCU_DSV_DSLPVS; - RCU_DSV = dsvol; -} - /*! \brief configure the spread spectrum modulation for the main PLL clock \param[in] spread_spectrum_type: PLL spread spectrum modulation type select @@ -1214,7 +1030,7 @@ void rcu_deepsleep_voltage_set(uint32_t dsvol) void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt) { uint32_t reg; - + reg = RCU_PLLSSCTL; /* reset the RCU_PLLSSCTL register bits */ reg &= ~(RCU_PLLSSCTL_MODCNT | RCU_PLLSSCTL_MODSTEP | RCU_PLLSSCTL_SS_TYPE); @@ -1243,6 +1059,57 @@ void rcu_spread_spectrum_disable(void) RCU_PLLSSCTL &= ~RCU_PLLSSCTL_SSCGON; } +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ + +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_CKMEN; +} + +/*! + \brief unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + RCU_VKEY = RCU_VKEY_UNLOCK; +} + +/*! + \brief deep-sleep mode voltage select + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_0: the core voltage is default value + \arg RCU_DEEPSLEEP_V_1: the core voltage is (default value-0.1)V(customers are not recommended to use it) + \arg RCU_DEEPSLEEP_V_2: the core voltage is (default value-0.2)V(customers are not recommended to use it) + \arg RCU_DEEPSLEEP_V_3: the core voltage is (default value-0.3)V(customers are not recommended to use it) + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + dsvol &= RCU_DSV_DSLPVS; + RCU_DSV = dsvol; +} + /*! \brief get the system clock, bus and peripheral clock frequency \param[in] clock: the clock frequency which to get @@ -1259,14 +1126,14 @@ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) uint32_t sws, ck_freq = 0U; uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq; uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp; - + /* exponent of AHB, APB1 and APB2 clock divider */ const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; sws = GET_BITS(RCU_CFG0, 2, 3); - switch(sws){ + switch(sws) { /* IRC16M is selected as CK_SYS */ case SEL_IRC16M: cksys_freq = IRC16M_VALUE; @@ -1283,12 +1150,12 @@ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U; /* PLL clock source selection, HXTAL or IRC16M/2 */ pllsel = (RCU_PLL & RCU_PLL_PLLSEL); - if (RCU_PLLSRC_HXTAL == pllsel) { + if(RCU_PLLSRC_HXTAL == pllsel) { ck_src = HXTAL_VALUE; } else { ck_src = IRC16M_VALUE; } - cksys_freq = ((ck_src / pllpsc) * plln)/pllp; + cksys_freq = ((ck_src / pllpsc) * plln) / pllp; break; /* IRC16M is selected as CK_SYS */ default: @@ -1299,19 +1166,19 @@ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) idx = GET_BITS(RCU_CFG0, 4, 7); clk_exp = ahb_exp[idx]; ahb_freq = cksys_freq >> clk_exp; - + /* calculate APB1 clock frequency */ idx = GET_BITS(RCU_CFG0, 10, 12); clk_exp = apb1_exp[idx]; apb1_freq = ahb_freq >> clk_exp; - + /* calculate APB2 clock frequency */ idx = GET_BITS(RCU_CFG0, 13, 15); clk_exp = apb2_exp[idx]; apb2_freq = ahb_freq >> clk_exp; - + /* return the clocks frequency */ - switch(clock){ + switch(clock) { case CK_SYS: ck_freq = cksys_freq; break; @@ -1329,3 +1196,134 @@ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) } return ck_freq; } + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC16MSTB: IRC16M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_PLLI2SSTB: PLLI2S stabilization flag + \arg RCU_FLAG_PLLSAISTB: PLLSAI stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC32KSTB: IRC32K stabilization flag + \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag + \arg RCU_FLAG_BORRST: BOR reset flags + \arg RCU_FLAG_EPRST: external PIN reset flag + \arg RCU_FLAG_PORRST: Power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval none +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + /* get the rcu flag */ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear all the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB: IRC32K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC16MSTB: IRC16M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLI2SSTB: PLLI2S stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSAISTB: PLLSAI stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_IRC48MSTB: IRC48M stabilization interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + /* get the rcu interrupt flag */ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB_CLR: IRC32K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC16MSTB_CLR: IRC16M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLI2SSTB_CLR: PLLI2S stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSAISTB_CLR: PLLSAI stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \arg RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag) +{ + RCU_REG_VAL(int_flag) |= BIT(RCU_BIT_POS(int_flag)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum + Only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt enable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt enable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) |= BIT(RCU_BIT_POS(interrupt)); +} + + +/*! + \brief disable the stabilization interrupt + \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC16MSTB: IRC16M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt disable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt disable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) &= ~BIT(RCU_BIT_POS(interrupt)); +} diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c index 207d445..b7baf3a 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c @@ -2,35 +2,33 @@ \file gd32f4xx_rtc.c \brief RTC driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -45,7 +43,6 @@ OF SUCH DAMAGE. #define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ #define RTC_ALRMXWF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ - /*! \brief reset most of the RTC registers \param[in] none @@ -67,7 +64,7 @@ ErrStatus rtc_deinit(void) /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ + if(ERROR != error_status) { /* reset RTC_CTL register, but RTC_CTL[2��0] */ RTC_CTL &= (RTC_REGISTER_RESET | RTC_CTL_WTCS); /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. @@ -78,18 +75,18 @@ ErrStatus rtc_deinit(void) RTC_PSC = RTC_PSC_RESET; /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2��0] */ /* wait until the WTWF flag to be set */ - do{ - flag_status = RTC_STAT & RTC_STAT_WTWF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + do { + flag_status = RTC_STAT & RTC_STAT_WTWF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET == flag_status){ + if((uint32_t)RESET == flag_status) { error_status = ERROR; - }else{ + } else { RTC_CTL &= RTC_REGISTER_RESET; RTC_WUT = RTC_WUT_RESET; RTC_COSC = RTC_REGISTER_RESET; /* to write RTC_ALRMxSS register, ALRMxEN bit in RTC_CTL register should be reset as the condition */ - RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0TD = RTC_REGISTER_RESET; RTC_ALRM1TD = RTC_REGISTER_RESET; RTC_ALRM0SS = RTC_REGISTER_RESET; RTC_ALRM1SS = RTC_REGISTER_RESET; @@ -97,9 +94,9 @@ ErrStatus rtc_deinit(void) at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ RTC_STAT = RTC_STAT_RESET; /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ - RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_SHIFTCTL = RTC_REGISTER_RESET; RTC_HRFC = RTC_REGISTER_RESET; - error_status = rtc_register_sync_wait(); + error_status = rtc_register_sync_wait(); } } @@ -111,7 +108,7 @@ ErrStatus rtc_deinit(void) /*! \brief initialize RTC registers - \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains parameters for initialization of the rtc peripheral members of the structure and the member values are shown as below: year: 0x0 - 0x99(BCD format) @@ -130,7 +127,7 @@ ErrStatus rtc_deinit(void) \param[out] none \retval ErrStatus: ERROR or SUCCESS */ -ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct) { ErrStatus error_status = ERROR; uint32_t reg_time = 0U, reg_date = 0U; @@ -138,13 +135,13 @@ ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) reg_date = (DATE_YR(rtc_initpara_struct->year) | \ DATE_DOW(rtc_initpara_struct->day_of_week) | \ DATE_MON(rtc_initpara_struct->month) | \ - DATE_DAY(rtc_initpara_struct->date)); - - reg_time = (rtc_initpara_struct->am_pm| \ + DATE_DAY(rtc_initpara_struct->date)); + + reg_time = (rtc_initpara_struct->am_pm | \ TIME_HR(rtc_initpara_struct->hour) | \ TIME_MN(rtc_initpara_struct->minute) | \ - TIME_SC(rtc_initpara_struct->second)); - + TIME_SC(rtc_initpara_struct->second)); + /* 1st: disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -152,8 +149,8 @@ ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) /* 2nd: enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ - RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \ + if(ERROR != error_status) { + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn) | \ PSC_FACTOR_S(rtc_initpara_struct->factor_syn)); RTC_TIME = (uint32_t)reg_time; @@ -161,10 +158,10 @@ ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) RTC_CTL &= (uint32_t)(~RTC_CTL_CS); RTC_CTL |= rtc_initpara_struct->display_format; - - /* 3rd: exit init mode */ + + /* 3rd: exit init mode */ rtc_init_mode_exit(); - + /* 4th: wait the RSYNF flag to set */ error_status = rtc_register_sync_wait(); } @@ -188,18 +185,18 @@ ErrStatus rtc_init_mode_enter(void) ErrStatus error_status = ERROR; /* check whether it has been in init mode */ - if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)) { RTC_STAT |= RTC_STAT_INITM; - + /* wait until the INITF flag to be set */ - do{ - flag_status = RTC_STAT & RTC_STAT_INITF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + do { + flag_status = RTC_STAT & RTC_STAT_INITF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET != flag_status){ + if((uint32_t)RESET != flag_status) { error_status = SUCCESS; } - }else{ + } else { error_status = SUCCESS; } return error_status; @@ -217,7 +214,7 @@ void rtc_init_mode_exit(void) } /*! - \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated \param[in] none \param[out] none @@ -229,7 +226,7 @@ ErrStatus rtc_register_sync_wait(void) uint32_t flag_status = RESET; ErrStatus error_status = ERROR; - if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)) { /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -238,17 +235,17 @@ ErrStatus rtc_register_sync_wait(void) RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); /* wait until RSYNF flag to be set */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_RSYNF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET != flag_status){ + if((uint32_t)RESET != flag_status) { error_status = SUCCESS; } - + /* enable the write protection */ RTC_WPK = RTC_LOCK_KEY; - }else{ + } else { error_status = SUCCESS; } @@ -258,7 +255,7 @@ ErrStatus rtc_register_sync_wait(void) /*! \brief get current time and date \param[in] none - \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains parameters for initialization of the rtc peripheral members of the structure and the member values are shown as below: year: 0x0 - 0x99(BCD format) @@ -276,26 +273,26 @@ ErrStatus rtc_register_sync_wait(void) display_format: RTC_24HOUR, RTC_12HOUR \retval none */ -void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +void rtc_current_time_get(rtc_parameter_struct *rtc_initpara_struct) { uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U; - temp_tr = (uint32_t)RTC_TIME; + temp_tr = (uint32_t)RTC_TIME; temp_dr = (uint32_t)RTC_DATE; temp_pscr = (uint32_t)RTC_PSC; temp_ctlr = (uint32_t)RTC_CTL; - + /* get current time and construct rtc_parameter_struct structure */ rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr); rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr); rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr); - rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr); rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr); rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr); rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); - rtc_initpara_struct->am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->am_pm = (uint32_t)(temp_tr & RTC_TIME_PM); rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); } @@ -311,7 +308,7 @@ uint32_t rtc_subsecond_get(void) /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ reg = (uint32_t)RTC_SS; /* read RTC_DATE to unlock the 3 shadow registers */ - (void) (RTC_DATE); + (void)(RTC_DATE); return reg; } @@ -319,7 +316,7 @@ uint32_t rtc_subsecond_get(void) /*! \brief configure RTC alarm \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 - \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains parameters for RTC alarm configuration members of the structure and the member values are shown as below: alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK @@ -335,26 +332,26 @@ uint32_t rtc_subsecond_get(void) \param[out] none \retval none */ -void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time) +void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time) { uint32_t reg_alrmtd = 0U; - reg_alrmtd =(rtc_alarm_time->alarm_mask | \ - rtc_alarm_time->weekday_or_date | \ - rtc_alarm_time->am_pm | \ - ALRMTD_DAY(rtc_alarm_time->alarm_day) | \ - ALRMTD_HR(rtc_alarm_time->alarm_hour) | \ - ALRMTD_MN(rtc_alarm_time->alarm_minute) | \ - ALRMTD_SC(rtc_alarm_time->alarm_second)); + reg_alrmtd = (rtc_alarm_time->alarm_mask | \ + rtc_alarm_time->weekday_or_date | \ + rtc_alarm_time->am_pm | \ + ALRMTD_DAY(rtc_alarm_time->alarm_day) | \ + ALRMTD_HR(rtc_alarm_time->alarm_hour) | \ + ALRMTD_MN(rtc_alarm_time->alarm_minute) | \ + ALRMTD_SC(rtc_alarm_time->alarm_second)); /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - if(RTC_ALARM0 == rtc_alarm){ + if(RTC_ALARM0 == rtc_alarm) { RTC_ALRM0TD = (uint32_t)reg_alrmtd; - - }else{ + + } else { RTC_ALRM1TD = (uint32_t)reg_alrmtd; } /* enable the write protection */ @@ -389,12 +386,12 @@ void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint { /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; - RTC_WPK = RTC_UNLOCK_KEY2; + RTC_WPK = RTC_UNLOCK_KEY2; - if(RTC_ALARM0 == rtc_alarm){ - RTC_ALRM0SS = mask_subsecond | subsecond; - }else{ - RTC_ALRM1SS = mask_subsecond | subsecond; + if(RTC_ALARM0 == rtc_alarm) { + RTC_ALRM0SS = mask_subsecond | subsecond; + } else { + RTC_ALRM1SS = mask_subsecond | subsecond; } /* enable the write protection */ RTC_WPK = RTC_LOCK_KEY; @@ -403,7 +400,7 @@ void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint /*! \brief get RTC alarm \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 - \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains parameters for RTC alarm configuration members of the structure and the member values are shown as below: alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK @@ -418,24 +415,24 @@ void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint am_pm: RTC_AM, RTC_PM \retval none */ -void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time) +void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time) { uint32_t reg_alrmtd = 0U; /* get the value of RTC_ALRM0TD register */ - if(RTC_ALARM0 == rtc_alarm){ + if(RTC_ALARM0 == rtc_alarm) { reg_alrmtd = RTC_ALRM0TD; - }else{ + } else { reg_alrmtd = RTC_ALRM1TD; } /* get alarm parameters and construct the rtc_alarm_struct structure */ - rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK; + rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK; rtc_alarm_time->am_pm = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_PM); rtc_alarm_time->weekday_or_date = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_DOWS); rtc_alarm_time->alarm_day = (uint8_t)GET_ALRMTD_DAY(reg_alrmtd); rtc_alarm_time->alarm_hour = (uint8_t)GET_ALRMTD_HR(reg_alrmtd); rtc_alarm_time->alarm_minute = (uint8_t)GET_ALRMTD_MN(reg_alrmtd); - rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd); + rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd); } /*! @@ -446,9 +443,9 @@ void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time) */ uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm) { - if(RTC_ALARM0 == rtc_alarm){ + if(RTC_ALARM0 == rtc_alarm) { return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); - }else{ + } else { return ((uint32_t)(RTC_ALRM1SS & RTC_ALRM1SS_SSC)); } } @@ -465,9 +462,9 @@ void rtc_alarm_enable(uint8_t rtc_alarm) RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - if(RTC_ALARM0 == rtc_alarm){ + if(RTC_ALARM0 == rtc_alarm) { RTC_CTL |= RTC_CTL_ALRM0EN; - }else{ + } else { RTC_CTL |= RTC_CTL_ALRM1EN; } /* enable the write protection */ @@ -489,23 +486,23 @@ ErrStatus rtc_alarm_disable(uint8_t rtc_alarm) /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + /* clear the state of alarm */ - if(RTC_ALARM0 == rtc_alarm){ - RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + if(RTC_ALARM0 == rtc_alarm) { + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); /* wait until ALRM0WF flag to be set after the alarm is disabled */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_ALRM0WF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - }else{ - RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } else { + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN); /* wait until ALRM1WF flag to be set after the alarm is disabled */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_ALRM1WF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); } - - if ((uint32_t)RESET != flag_status){ + + if((uint32_t)RESET != flag_status) { error_status = SUCCESS; } @@ -532,7 +529,7 @@ void rtc_timestamp_enable(uint32_t edge) /* new configuration */ reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); - + /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -554,7 +551,7 @@ void rtc_timestamp_disable(void) /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + /* clear the TSEN bit */ RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); @@ -565,7 +562,7 @@ void rtc_timestamp_disable(void) /*! \brief get RTC timestamp time and date \param[in] none - \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains parameters for RTC time-stamp configuration members of the structure and the member values are shown as below: timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, @@ -579,14 +576,14 @@ void rtc_timestamp_disable(void) am_pm: RTC_AM, RTC_PM \retval none */ -void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +void rtc_timestamp_get(rtc_timestamp_struct *rtc_timestamp) { uint32_t temp_tts = 0U, temp_dts = 0U; /* get the value of time_stamp registers */ temp_tts = (uint32_t)RTC_TTS; temp_dts = (uint32_t)RTC_DTS; - + /* get timestamp time and construct the rtc_timestamp_struct structure */ rtc_timestamp->am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); rtc_timestamp->timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); @@ -609,7 +606,7 @@ uint32_t rtc_timestamp_subsecond_get(void) } /*! - \brief RTC time-stamp mapping + \brief RTC time-stamp mapping \param[in] rtc_af: \arg RTC_AF0_TIMESTAMP: RTC_AF0 use for timestamp \arg RTC_AF1_TIMESTAMP: RTC_AF1 use for timestamp @@ -624,7 +621,7 @@ void rtc_timestamp_pin_map(uint32_t rtc_af) /*! \brief enable RTC tamper - \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains parameters for RTC tamper configuration members of the structure and the member values are shown as below: detecting tamper event can using edge mode or level mode @@ -646,49 +643,49 @@ void rtc_timestamp_pin_map(uint32_t rtc_af) \param[out] none \retval none */ -void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +void rtc_tamper_enable(rtc_tamper_struct *rtc_tamper) { /* disable tamper */ - RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source); + RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source); /* tamper filter must be used when the tamper source is voltage level detection */ RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; - + /* the tamper source is voltage level detection */ - if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE ){ + if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE) { RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); /* check if the tamper pin need precharge, if need, then configure the precharge time */ - if(DISABLE == rtc_tamper->tamper_precharge_enable){ - RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; - }else{ + if(DISABLE == rtc_tamper->tamper_precharge_enable) { + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + } else { RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_precharge_time); } RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_sample_frequency); RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_filter); - + /* configure the tamper trigger */ - RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); - if(RTC_TAMPER_TRIGGER_LEVEL_LOW != rtc_tamper->tamper_trigger){ - RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source)<< RTC_TAMPER_TRIGGER_POS); + RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_LEVEL_LOW != rtc_tamper->tamper_trigger) { + RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS); } - }else{ - + } else { + /* configure the tamper trigger */ - RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); - if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger){ - RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source)<< RTC_TAMPER_TRIGGER_POS); + RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger) { + RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS); } } - - RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; - if(DISABLE != rtc_tamper->tamper_with_timestamp){ + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + if(DISABLE != rtc_tamper->tamper_with_timestamp) { /* the tamper event also cause a time-stamp event */ RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; - } + } /* enable tamper */ - RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_source); + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_source); } /*! @@ -702,12 +699,12 @@ void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) void rtc_tamper_disable(uint32_t source) { /* disable tamper */ - RTC_TAMP &= (uint32_t)~source; + RTC_TAMP &= (uint32_t)~source; } /*! - \brief RTC tamper0 mapping + \brief RTC tamper0 mapping \param[in] rtc_af: \arg RTC_AF0_TAMPER0: RTC_AF0 use for tamper0 \arg RTC_AF1_TAMPER0: RTC_AF1 use for tamper0 @@ -732,18 +729,18 @@ void rtc_tamper0_pin_map(uint32_t rtc_af) \retval none */ void rtc_interrupt_enable(uint32_t interrupt) -{ +{ /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + /* enable the interrupts in RTC_CTL register */ RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); /* enable the interrupts in RTC_TAMP register */ RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); - + /* enable the write protection */ - RTC_WPK = RTC_LOCK_KEY; + RTC_WPK = RTC_LOCK_KEY; } /*! @@ -758,11 +755,11 @@ void rtc_interrupt_enable(uint32_t interrupt) \retval none */ void rtc_interrupt_disable(uint32_t interrupt) -{ +{ /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + /* disable the interrupts in RTC_CTL register */ RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); /* disable the interrupts in RTC_TAMP register */ @@ -779,7 +776,7 @@ void rtc_interrupt_disable(uint32_t interrupt) \arg RTC_FLAG_TP1: RTC tamper 1 detected flag \arg RTC_FLAG_TP0: RTC tamper 0 detected flag \arg RTC_FLAG_TSOVR: time-stamp overflow flag - \arg RTC_FLAG_TS: time-stamp flag + \arg RTC_FLAG_TS: time-stamp flag \arg RTC_FLAG_ALRM0: alarm0 occurs flag \arg RTC_FLAG_ALRM1: alarm1 occurs flag \arg RTC_FLAG_WT: wakeup timer occurs flag @@ -796,8 +793,8 @@ void rtc_interrupt_disable(uint32_t interrupt) FlagStatus rtc_flag_get(uint32_t flag) { FlagStatus flag_state = RESET; - - if ((uint32_t)RESET != (RTC_STAT & flag)){ + + if((uint32_t)RESET != (RTC_STAT & flag)) { flag_state = SET; } return flag_state; @@ -818,7 +815,7 @@ FlagStatus rtc_flag_get(uint32_t flag) */ void rtc_flag_clear(uint32_t flag) { - RTC_STAT &= (uint32_t)(~flag); + RTC_STAT &= (uint32_t)(~flag); } /*! @@ -856,9 +853,9 @@ void rtc_alarm_output_config(uint32_t source, uint32_t mode) /*! \brief configure rtc calibration output source \param[in] source: specify signal to output - \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC + \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC is the default value, output 512Hz signal - \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC + \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC is the default value, output 1Hz signal \param[out] none \retval none @@ -876,7 +873,6 @@ void rtc_calibration_output_config(uint32_t source) RTC_WPK = RTC_LOCK_KEY; } - /*! \brief adjust the daylight saving time by adding or substracting one hour from the current time \param[in] operation: hour adjustment operation @@ -890,7 +886,7 @@ void rtc_hour_adjust(uint32_t operation) /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + RTC_CTL |= (uint32_t)(operation); /* enable the write protection */ @@ -911,21 +907,21 @@ ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; ErrStatus error_status = ERROR; uint32_t flag_status = RESET; - uint32_t temp=0U; + uint32_t temp = 0U; /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - - /* check if a shift operation is ongoing */ - do{ + + /* check if a shift operation is ongoing */ + do { flag_status = RTC_STAT & RTC_STAT_SOPF; - }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); - + } while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + /* check if the function of reference clock detection is disabled */ temp = RTC_CTL & RTC_CTL_REFEN; - if((RESET == flag_status) && (RESET == temp)){ + if((RESET == flag_status) && (RESET == temp)) { RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); - error_status = rtc_register_sync_wait(); + error_status = rtc_register_sync_wait(); } /* enable the write protection */ @@ -941,7 +937,7 @@ ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) \retval none */ void rtc_bypass_shadow_enable(void) -{ +{ /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -959,7 +955,7 @@ void rtc_bypass_shadow_enable(void) \retval none */ void rtc_bypass_shadow_disable(void) -{ +{ /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -979,7 +975,7 @@ void rtc_bypass_shadow_disable(void) ErrStatus rtc_refclock_detection_enable(void) { ErrStatus error_status = ERROR; - + /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -987,7 +983,7 @@ ErrStatus rtc_refclock_detection_enable(void) /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ + if(ERROR != error_status) { RTC_CTL |= (uint32_t)RTC_CTL_REFEN; /* exit init mode */ rtc_init_mode_exit(); @@ -1008,7 +1004,7 @@ ErrStatus rtc_refclock_detection_enable(void) ErrStatus rtc_refclock_detection_disable(void) { ErrStatus error_status = ERROR; - + /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; @@ -1016,7 +1012,7 @@ ErrStatus rtc_refclock_detection_disable(void) /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ + if(ERROR != error_status) { RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; /* exit init mode */ rtc_init_mode_exit(); @@ -1038,7 +1034,7 @@ void rtc_wakeup_enable(void) { /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; - RTC_WPK = RTC_UNLOCK_KEY2; + RTC_WPK = RTC_UNLOCK_KEY2; RTC_CTL |= RTC_CTL_WTEN; @@ -1062,13 +1058,13 @@ ErrStatus rtc_wakeup_disable(void) RTC_WPK = RTC_UNLOCK_KEY2; RTC_CTL &= ~RTC_CTL_WTEN; /* wait until the WTWF flag to be set */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_WTWF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET == flag_status){ + if((uint32_t)RESET == flag_status) { error_status = ERROR; - }else{ + } else { error_status = SUCCESS; } /* enable the write protection */ @@ -1079,12 +1075,12 @@ ErrStatus rtc_wakeup_disable(void) /*! \brief set RTC auto wakeup timer clock \param[in] wakeup_clock: - \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 - \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 - \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 - \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 + \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 + \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 + \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 + \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 \arg WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre - \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 + \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 \param[out] none \retval ErrStatus: ERROR or SUCCESS */ @@ -1095,23 +1091,23 @@ ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock) uint32_t flag_status = RESET; /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; - RTC_WPK = RTC_UNLOCK_KEY2; + RTC_WPK = RTC_UNLOCK_KEY2; /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2��0] */ /* wait until the WTWF flag to be set */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_WTWF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET == flag_status){ + if((uint32_t)RESET == flag_status) { error_status = ERROR; - }else{ + } else { RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS; RTC_CTL |= (uint32_t)wakeup_clock; error_status = SUCCESS; } /* enable the write protection */ RTC_WPK = RTC_LOCK_KEY; - + return error_status; } @@ -1130,13 +1126,13 @@ ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; /* wait until the WTWF flag to be set */ - do{ + do { flag_status = RTC_STAT & RTC_STAT_WTWF; - }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); - if ((uint32_t)RESET == flag_status){ + if((uint32_t)RESET == flag_status) { error_status = ERROR; - }else{ + } else { RTC_WUT = (uint32_t)wakeup_timer; error_status = SUCCESS; } @@ -1151,7 +1147,7 @@ ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) \param[out] none \retval wakeup timer value */ - uint16_t rtc_wakeup_timer_get(void) +uint16_t rtc_wakeup_timer_get(void) { return (uint16_t)RTC_WUT; } @@ -1174,17 +1170,17 @@ ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t volatile uint32_t time_index = RTC_HRFC_TIMEOUT; ErrStatus error_status = ERROR; uint32_t flag_status = RESET; - + /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; - RTC_WPK = RTC_UNLOCK_KEY2; - - /* check if a smooth calibration operation is ongoing */ - do{ + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a smooth calibration operation is ongoing */ + do { flag_status = RTC_STAT & RTC_STAT_SCPF; - }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); - - if((uint32_t)RESET == flag_status){ + } while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status) { RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); error_status = SUCCESS; } @@ -1210,12 +1206,12 @@ ErrStatus rtc_coarse_calibration_enable(void) /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ + if(ERROR != error_status) { RTC_CTL |= (uint32_t)RTC_CTL_CCEN; /* exit init mode */ rtc_init_mode_exit(); } - + /* enable the write protection */ RTC_WPK = RTC_LOCK_KEY; return error_status; @@ -1232,24 +1228,24 @@ ErrStatus rtc_coarse_calibration_disable(void) ErrStatus error_status = ERROR; /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; - RTC_WPK = RTC_UNLOCK_KEY2; + RTC_WPK = RTC_UNLOCK_KEY2; /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ + if(ERROR != error_status) { RTC_CTL &= (uint32_t)~RTC_CTL_CCEN; /* exit init mode */ rtc_init_mode_exit(); } - + /* enable the write protection */ - RTC_WPK = RTC_LOCK_KEY; + RTC_WPK = RTC_LOCK_KEY; return error_status; } /*! \brief config coarse calibration direction and step - \param[in] direction: CALIB_INCREASE or CALIB_DECREASE + \param[in] direction: CALIB_INCREASE or CALIB_DECREASE \param[in] step: 0x00-0x1F COSD=0: 0x00:+0 PPM @@ -1272,14 +1268,14 @@ ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step) /* disable the write protection */ RTC_WPK = RTC_UNLOCK_KEY1; RTC_WPK = RTC_UNLOCK_KEY2; - + /* enter init mode */ error_status = rtc_init_mode_enter(); - if(ERROR != error_status){ - if(CALIB_DECREASE == direction){ + if(ERROR != error_status) { + if(CALIB_DECREASE == direction) { RTC_COSC |= (uint32_t)RTC_COSC_COSD; - }else{ + } else { RTC_COSC &= (uint32_t)~RTC_COSC_COSD; } RTC_COSC &= ~RTC_COSC_COSS; @@ -1287,9 +1283,9 @@ ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step) /* exit init mode */ rtc_init_mode_exit(); } - + /* enable the write protection */ RTC_WPK = RTC_LOCK_KEY; - + return error_status; } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c index fdaae06..a17a56c 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_sdio.c \brief SDIO driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.1, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -73,7 +71,7 @@ void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t cloc /* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */ clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV); /* if the clock division is greater or equal to 256, set the DIV[8] */ - if(clock_division >= 256U){ + if(clock_division >= 256U) { clock_config |= SDIO_CLKCTL_DIV8; clock_division -= 256U; } @@ -262,7 +260,7 @@ uint8_t sdio_command_index_get(void) uint32_t sdio_response_get(uint32_t sdio_responsex) { uint32_t resp_content = 0U; - switch(sdio_responsex){ + switch(sdio_responsex) { case SDIO_RESPONSE0: resp_content = SDIO_RESP0; break; @@ -462,7 +460,7 @@ void sdio_dma_disable(void) FlagStatus sdio_flag_get(uint32_t flag) { FlagStatus temp_flag = RESET; - if(RESET != (SDIO_STAT & flag)){ + if(RESET != (SDIO_STAT & flag)) { temp_flag = SET; } return temp_flag; @@ -599,7 +597,7 @@ void sdio_interrupt_disable(uint32_t int_flag) FlagStatus sdio_interrupt_flag_get(uint32_t int_flag) { FlagStatus temp_flag = RESET; - if(RESET != (SDIO_STAT & int_flag)){ + if(RESET != (SDIO_STAT & int_flag)) { temp_flag = SET; } return temp_flag; @@ -685,9 +683,9 @@ void sdio_stop_readwait_disable(void) */ void sdio_readwait_type_set(uint32_t readwait_type) { - if(SDIO_READWAITTYPE_CLK == readwait_type){ + if(SDIO_READWAITTYPE_CLK == readwait_type) { SDIO_DATACTL |= SDIO_DATACTL_RWTYPE; - }else{ + } else { SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c index 2ee9c86..456ae2a 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c @@ -2,35 +2,33 @@ \file gd32f4xx_spi.c \brief SPI driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -47,14 +45,14 @@ OF SUCH DAMAGE. #define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */ /*! - \brief deinitialize SPI and I2S + \brief deinitialize SPI and I2S \param[in] spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD \param[out] none \retval none */ void spi_i2s_deinit(uint32_t spi_periph) { - switch(spi_periph){ + switch(spi_periph) { case SPI0: /* reset SPI0 */ rcu_periph_reset_enable(RCU_SPI0RST); @@ -91,7 +89,7 @@ void spi_i2s_deinit(uint32_t spi_periph) } /*! - \brief initialize the parameters of SPI struct with default values + \brief initialize the parameters of SPI struct with default values \param[in] none \param[out] spi_parameter_struct: the initialized struct spi_parameter_struct pointer \retval none @@ -108,7 +106,7 @@ void spi_struct_para_init(spi_parameter_struct *spi_struct) spi_struct->endian = SPI_ENDIAN_MSB; } /*! - \brief initialize SPI parameter + \brief initialize SPI parameter \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_struct: SPI parameter initialization stuct members of the structure and the member values are shown as below: @@ -124,8 +122,8 @@ void spi_struct_para_init(spi_parameter_struct *spi_struct) \param[out] none \retval none */ -void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) -{ +void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct) +{ uint32_t reg = 0U; reg = SPI_CTL0(spi_periph); reg &= SPI_INIT_MASK; @@ -152,7 +150,7 @@ void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) } /*! - \brief enable SPI + \brief enable SPI \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -163,7 +161,7 @@ void spi_enable(uint32_t spi_periph) } /*! - \brief disable SPI + \brief disable SPI \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -174,7 +172,7 @@ void spi_disable(uint32_t spi_periph) } /*! - \brief initialize I2S parameter + \brief initialize I2S parameter \param[in] spi_periph: SPIx(x=1,2) \param[in] i2s_mode: I2S operation mode only one parameter can be selected which is shown as below: @@ -198,12 +196,12 @@ void spi_disable(uint32_t spi_periph) */ void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl) { - uint32_t reg= 0U; + uint32_t reg = 0U; reg = SPI_I2SCTL(spi_periph); reg &= I2S_INIT_MASK; /* enable I2S mode */ - reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; /* select I2S mode */ reg |= (uint32_t)i2s_mode; /* select I2S standard */ @@ -216,7 +214,7 @@ void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uin } /*! - \brief configure I2S prescale + \brief configure I2S prescale \param[in] spi_periph: SPIx(x=1,2) \param[in] i2s_audiosample: I2S audio sample rate only one parameter can be selected which is shown as below: @@ -249,7 +247,7 @@ void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_ uint32_t i2sclock = 0U; #ifndef I2S_EXTERNAL_CLOCK_IN - uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U; + uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U; #endif /* I2S_EXTERNAL_CLOCK_IN */ /* deinit SPI_I2SPSC register */ @@ -280,25 +278,23 @@ void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_ /* get the RCU_PLLI2S_PLLI2SR value */ plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28); - if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL) - { - /* get the I2S source clock value */ - i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr); - } - else - { /* get the I2S source clock value */ - i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr); + if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL) { + /* get the I2S source clock value */ + i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr); + } else { + /* get the I2S source clock value */ + i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr); } #endif /* I2S_EXTERNAL_CLOCK_IN */ /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ - if(I2S_MCKOUT_ENABLE == i2s_mckout){ + if(I2S_MCKOUT_ENABLE == i2s_mckout) { clks = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample); - }else{ - if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat){ - clks = (uint32_t)(((i2sclock / 32U) *10U ) / i2s_audiosample); - }else{ - clks = (uint32_t)(((i2sclock / 64U) *10U ) / i2s_audiosample); + } else { + if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat) { + clks = (uint32_t)(((i2sclock / 32U) * 10U) / i2s_audiosample); + } else { + clks = (uint32_t)(((i2sclock / 64U) * 10U) / i2s_audiosample); } } /* remove the floating point */ @@ -308,7 +304,7 @@ void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_ i2sof = (i2sof << 8U); /* set the default values */ - if((i2sdiv< 2U) || (i2sdiv > 255U)){ + if((i2sdiv < 2U) || (i2sdiv > 255U)) { i2sdiv = 2U; i2sof = 0U; } @@ -317,13 +313,13 @@ void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_ SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | i2s_mckout); /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ - SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN|SPI_I2SCTL_CHLEN)); + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); /* configure data frame format */ SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat; } /*! - \brief enable I2S + \brief enable I2S \param[in] spi_periph: SPIx(x=1,2) \param[out] none \retval none @@ -334,7 +330,7 @@ void i2s_enable(uint32_t spi_periph) } /*! - \brief disable I2S + \brief disable I2S \param[in] spi_periph: SPIx(x=1,2) \param[out] none \retval none @@ -345,7 +341,7 @@ void i2s_disable(uint32_t spi_periph) } /*! - \brief enable SPI nss output + \brief enable SPI nss output \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -356,7 +352,7 @@ void spi_nss_output_enable(uint32_t spi_periph) } /*! - \brief disable SPI nss output + \brief disable SPI nss output \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -367,7 +363,7 @@ void spi_nss_output_disable(uint32_t spi_periph) } /*! - \brief SPI nss pin high level in software mode + \brief SPI nss pin high level in software mode \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -378,7 +374,7 @@ void spi_nss_internal_high(uint32_t spi_periph) } /*! - \brief SPI nss pin low level in software mode + \brief SPI nss pin low level in software mode \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -389,7 +385,7 @@ void spi_nss_internal_low(uint32_t spi_periph) } /*! - \brief enable SPI DMA send or receive + \brief enable SPI DMA send or receive \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_dma: SPI DMA mode only one parameter can be selected which is shown as below: @@ -400,15 +396,15 @@ void spi_nss_internal_low(uint32_t spi_periph) */ void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma) { - if(SPI_DMA_TRANSMIT == spi_dma){ + if(SPI_DMA_TRANSMIT == spi_dma) { SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; - }else{ + } else { SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; } } /*! - \brief diable SPI DMA send or receive + \brief diable SPI DMA send or receive \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_dma: SPI DMA mode only one parameter can be selected which is shown as below: @@ -419,15 +415,15 @@ void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma) */ void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma) { - if(SPI_DMA_TRANSMIT == spi_dma){ + if(SPI_DMA_TRANSMIT == spi_dma) { SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); - }else{ + } else { SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); } } /*! - \brief configure SPI/I2S data frame format + \brief configure SPI/I2S data frame format \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] frame_format: SPI frame size only one parameter can be selected which is shown as below: @@ -445,7 +441,7 @@ void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format } /*! - \brief SPI transmit data + \brief SPI transmit data \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] data: 16-bit data \param[out] none @@ -457,7 +453,7 @@ void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) } /*! - \brief SPI receive data + \brief SPI receive data \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval 16-bit data @@ -468,7 +464,7 @@ uint16_t spi_i2s_data_receive(uint32_t spi_periph) } /*! - \brief configure SPI bidirectional transfer direction + \brief configure SPI bidirectional transfer direction \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] transfer_direction: SPI transfer direction only one parameter can be selected which is shown as below: @@ -478,30 +474,99 @@ uint16_t spi_i2s_data_receive(uint32_t spi_periph) */ void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) { - if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction) { /* set the transmit only mode */ SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; - }else{ + } else { /* set the receive only mode */ SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; } } /*! - \brief set SPI CRC polynomial + \brief configure i2s full duplex mode + \param[in] i2s_add_periph: I2Sx_ADD(x=1,2) + \param[in] i2s_mode: + \arg I2S_MODE_SLAVETX : I2S slave transmit mode + \arg I2S_MODE_SLAVERX : I2S slave receive mode + \arg I2S_MODE_MASTERTX : I2S master transmit mode + \arg I2S_MODE_MASTERRX : I2S master receive mode + \param[in] i2s_standard: + \arg I2S_STD_PHILLIPS : I2S phillips standard + \arg I2S_STD_MSB : I2S MSB standard + \arg I2S_STD_LSB : I2S LSB standard + \arg I2S_STD_PCMSHORT : I2S PCM short standard + \arg I2S_STD_PCMLONG : I2S PCM long standard + \param[in] i2s_ckpl: + \arg I2S_CKPL_LOW : I2S clock polarity low level + \arg I2S_CKPL_HIGH : I2S clock polarity high level + \param[in] i2s_frameformat: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[out] none + \retval none +*/ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, + uint32_t i2s_ckpl, uint32_t i2s_frameformat) +{ + uint32_t reg = 0U, tmp = 0U; + + reg = I2S_ADD_I2SCTL(i2s_add_periph); + reg &= I2S_FULL_DUPLEX_MASK; + + /* get the mode of the extra I2S module I2Sx_ADD */ + if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)) { + tmp = I2S_MODE_SLAVERX; + } else { + tmp = I2S_MODE_SLAVETX; + } + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)tmp; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + /* configure data frame format */ + reg |= (uint32_t)i2s_frameformat; + + /* write to SPI_I2SCTL register */ + I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg; +} + +/*! + \brief clear SPI/I2S format error flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] flag: SPI/I2S frame format error flag + \arg SPI_FLAG_FERR: only for SPI work in TI mode + \arg I2S_FLAG_FERR: for I2S + \param[out] none + \retval none +*/ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag) +{ + SPI_STAT(spi_periph) = (uint32_t)(~flag); +} + +/*! + \brief set SPI CRC polynomial \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] crc_poly: CRC polynomial value \param[out] none \retval none */ -void spi_crc_polynomial_set(uint32_t spi_periph,uint16_t crc_poly) +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly) { /* set SPI CRC polynomial */ SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; } /*! - \brief get SPI CRC polynomial + \brief get SPI CRC polynomial \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval 16-bit CRC polynomial @@ -512,7 +577,7 @@ uint16_t spi_crc_polynomial_get(uint32_t spi_periph) } /*! - \brief turn on CRC function + \brief turn on SPI CRC function \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -523,7 +588,7 @@ void spi_crc_on(uint32_t spi_periph) } /*! - \brief turn off CRC function + \brief turn off SPI CRC function \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -534,7 +599,7 @@ void spi_crc_off(uint32_t spi_periph) } /*! - \brief SPI next data is CRC value + \brief SPI next data is CRC value \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none @@ -545,7 +610,7 @@ void spi_crc_next(uint32_t spi_periph) } /*! - \brief get SPI CRC send value or receive value + \brief get SPI CRC send value or receive value \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_crc: SPI crc value only one parameter can be selected which is shown as below: @@ -554,160 +619,147 @@ void spi_crc_next(uint32_t spi_periph) \param[out] none \retval 16-bit CRC value */ -uint16_t spi_crc_get(uint32_t spi_periph,uint8_t spi_crc) +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t spi_crc) { - if(SPI_CRC_TX == spi_crc){ + if(SPI_CRC_TX == spi_crc) { return ((uint16_t)(SPI_TCRC(spi_periph))); - }else{ + } else { return ((uint16_t)(SPI_RCRC(spi_periph))); } } /*! - \brief enable SPI TI mode + \brief clear SPI CRC error flag status \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none */ -void spi_ti_mode_enable(uint32_t spi_periph) +void spi_crc_error_clear(uint32_t spi_periph) { - SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; + SPI_STAT(spi_periph) = (uint32_t)(~SPI_FLAG_CRCERR); } /*! - \brief disable SPI TI mode + \brief enable SPI TI mode \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none */ -void spi_ti_mode_disable(uint32_t spi_periph) +void spi_ti_mode_enable(uint32_t spi_periph) { - SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; } /*! - \brief configure i2s full duplex mode - \param[in] i2s_add_periph: I2Sx_ADD(x=1,2) - \param[in] i2s_mode: - \arg I2S_MODE_SLAVETX : I2S slave transmit mode - \arg I2S_MODE_SLAVERX : I2S slave receive mode - \arg I2S_MODE_MASTERTX : I2S master transmit mode - \arg I2S_MODE_MASTERRX : I2S master receive mode - \param[in] i2s_standard: - \arg I2S_STD_PHILLIPS : I2S phillips standard - \arg I2S_STD_MSB : I2S MSB standard - \arg I2S_STD_LSB : I2S LSB standard - \arg I2S_STD_PCMSHORT : I2S PCM short standard - \arg I2S_STD_PCMLONG : I2S PCM long standard - \param[in] i2s_ckpl: - \arg I2S_CKPL_LOW : I2S clock polarity low level - \arg I2S_CKPL_HIGH : I2S clock polarity high level - \param[in] i2s_frameformat: - \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit - \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit - \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit - \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[out] none \retval none */ -void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, - uint32_t i2s_ckpl, uint32_t i2s_frameformat) +void spi_ti_mode_disable(uint32_t spi_periph) { - uint32_t reg = 0U, tmp = 0U; - - reg = I2S_ADD_I2SCTL(i2s_add_periph); - reg &= I2S_FULL_DUPLEX_MASK; - - /* get the mode of the extra I2S module I2Sx_ADD */ - if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)){ - tmp = I2S_MODE_SLAVERX; - }else{ - tmp = I2S_MODE_SLAVETX; - } - - /* enable I2S mode */ - reg |= (uint32_t)SPI_I2SCTL_I2SSEL; - /* select I2S mode */ - reg |= (uint32_t)tmp; - /* select I2S standard */ - reg |= (uint32_t)i2s_standard; - /* select I2S polarity */ - reg |= (uint32_t)i2s_ckpl; - /* configure data frame format */ - reg |= (uint32_t)i2s_frameformat; - - /* write to SPI_I2SCTL register */ - I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg; + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); } /*! - \brief enable quad wire SPI + \brief enable quad wire SPI \param[in] spi_periph: SPIx(only x=5) \param[out] none \retval none */ -void qspi_enable(uint32_t spi_periph) +void spi_quad_enable(uint32_t spi_periph) { SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; } /*! - \brief disable quad wire SPI + \brief disable quad wire SPI \param[in] spi_periph: SPIx(only x=5) \param[out] none \retval none */ -void qspi_disable(uint32_t spi_periph) +void spi_quad_disable(uint32_t spi_periph) { SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); } /*! - \brief enable quad wire SPI write + \brief enable quad wire SPI write \param[in] spi_periph: SPIx(only x=5) \param[out] none \retval none */ -void qspi_write_enable(uint32_t spi_periph) +void spi_quad_write_enable(uint32_t spi_periph) { SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); } /*! - \brief enable quad wire SPI read + \brief enable quad wire SPI read \param[in] spi_periph: SPIx(only x=5) \param[out] none \retval none */ -void qspi_read_enable(uint32_t spi_periph) +void spi_quad_read_enable(uint32_t spi_periph) { SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; } /*! - \brief enable SPI_IO2 and SPI_IO3 pin output + \brief enable SPI_IO2 and SPI_IO3 pin output \param[in] spi_periph: SPIx(only x=5) \param[out] none \retval none */ -void qspi_io23_output_enable(uint32_t spi_periph) +void spi_quad_io23_output_enable(uint32_t spi_periph) { SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; } - /*! - \brief disable SPI_IO2 and SPI_IO3 pin output - \param[in] spi_periph: SPIx(only x=5) - \param[out] none - \retval none +/*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none */ - void qspi_io23_output_disable(uint32_t spi_periph) +void spi_quad_io23_output_disable(uint32_t spi_periph) { SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); } /*! - \brief enable SPI and I2S interrupt + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_flag: SPI/I2S flag status + only one parameter can be selected which are shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + \arg I2S_FLAG_FERR: format error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + if(SPI_STAT(spi_periph) & flag) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief enable SPI and I2S interrupt \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_i2s_int: SPI/I2S interrupt only one parameter can be selected which is shown as below: @@ -718,9 +770,9 @@ void qspi_io23_output_enable(uint32_t spi_periph) \param[out] none \retval none */ -void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int) +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) { - switch(spi_i2s_int){ + switch(interrupt) { /* SPI/I2S transmit buffer empty interrupt */ case SPI_I2S_INT_TBE: SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; @@ -739,7 +791,7 @@ void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int) } /*! - \brief disable SPI and I2S interrupt + \brief disable SPI and I2S interrupt \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_i2s_int: SPI/I2S interrupt only one parameter can be selected which is shown as below: @@ -750,9 +802,9 @@ void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t spi_i2s_int) \param[out] none \retval none */ -void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int) +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) { - switch(spi_i2s_int){ + switch(interrupt) { /* SPI/I2S transmit buffer empty interrupt */ case SPI_I2S_INT_TBE : SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); @@ -771,9 +823,10 @@ void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int) } /*! - \brief get SPI and I2S interrupt flag status + \brief get SPI and I2S interrupt flag status \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) \param[in] spi_i2s_int: SPI/I2S interrupt flag status + only one parameter can be selected which are shown as below: \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag @@ -784,12 +837,12 @@ void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t spi_i2s_int) \param[out] none \retval FlagStatus: SET or RESET */ -FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t spi_i2s_int) +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt) { uint32_t reg1 = SPI_STAT(spi_periph); uint32_t reg2 = SPI_CTL1(spi_periph); - switch(spi_i2s_int){ + switch(interrupt) { /* SPI/I2S transmit buffer empty interrupt */ case SPI_I2S_INT_FLAG_TBE : reg1 = reg1 & SPI_STAT_TBE; @@ -829,51 +882,9 @@ FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t spi_i2s_int) break; } /*get SPI/I2S interrupt flag status */ - if(reg1 && reg2){ + if(reg1 && reg2) { return SET; - }else{ + } else { return RESET; } } - -/*! - \brief get SPI and I2S flag status - \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) - \param[in] spi_i2s_flag: SPI/I2S flag status - \arg SPI_FLAG_TBE: transmit buffer empty flag - \arg SPI_FLAG_RBNE: receive buffer not empty flag - \arg SPI_FLAG_TRANS: transmit on-going flag - \arg SPI_FLAG_RXORERR: receive overrun error flag - \arg SPI_FLAG_CONFERR: mode config error flag - \arg SPI_FLAG_CRCERR: CRC error flag - \arg SPI_FLAG_FERR: format error flag - \arg I2S_FLAG_TBE: transmit buffer empty flag - \arg I2S_FLAG_RBNE: receive buffer not empty flag - \arg I2S_FLAG_TRANS: transmit on-going flag - \arg I2S_FLAG_RXORERR: overrun error flag - \arg I2S_FLAG_TXURERR: underrun error flag - \arg I2S_FLAG_CH: channel side flag - \arg I2S_FLAG_FERR: format error flag - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t spi_i2s_flag) -{ - if(SPI_STAT(spi_periph) & spi_i2s_flag){ - return SET; - }else{ - return RESET; - } -} - -/*! - \brief clear SPI CRC error flag status - \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) - \param[out] none - \retval none -*/ -void spi_crc_error_clear(uint32_t spi_periph) -{ - SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); -} - diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c index 4bd5bf8..bd16d61 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_syscfg.c \brief SYSCFG driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -49,7 +47,7 @@ void syscfg_deinit(void) } /*! - \brief configure the boot mode + \brief configure the boot mode \param[in] syscfg_bootmode: selects the memory remapping only one parameter can be selected which is shown as below: \arg SYSCFG_BOOTMODE_FLASH: main flash memory (0x08000000~0x083BFFFF) is mapped at address 0x00000000 @@ -120,7 +118,7 @@ void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); - switch(exti_pin/EXTI_SS_JSTEP){ + switch(exti_pin / EXTI_SS_JSTEP) { case EXTISS0: /* clear EXTI source line(0..3) */ SYSCFG_EXTISS0 &= clear_exti_mask; @@ -155,14 +153,14 @@ void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) \param[in] syscfg_enet_phy_interface: specifies the media interface mode. only one parameter can be selected which is shown as below: \arg SYSCFG_ENET_PHY_MII: MII mode is selected - \arg SYSCFG_ENET_PHY_RMII: RMII mode is selected + \arg SYSCFG_ENET_PHY_RMII: RMII mode is selected \param[out] none \retval none */ void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface) -{ +{ uint32_t reg; - + reg = SYSCFG_CFG1; /* reset the ENET_PHY_SEL bit and set according to syscfg_enet_phy_interface */ reg &= ~SYSCFG_CFG1_ENET_PHY_SEL; @@ -178,7 +176,7 @@ void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface) \param[out] none \retval none */ -void syscfg_compensation_config(uint32_t syscfg_compensation) +void syscfg_compensation_config(uint32_t syscfg_compensation) { uint32_t reg; @@ -196,9 +194,9 @@ void syscfg_compensation_config(uint32_t syscfg_compensation) */ FlagStatus syscfg_flag_get(void) { - if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)){ + if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)) { return SET; - }else{ + } else { return RESET; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c index 02b5194..a25e7b1 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c @@ -2,35 +2,33 @@ \file gd32f4xx_timer.c \brief TIMER driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -38,14 +36,14 @@ OF SUCH DAMAGE. #include "gd32f4xx_timer.h" /*! - \brief deinit a TIMER + \brief deinit a TIMER \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none */ void timer_deinit(uint32_t timer_periph) { - switch(timer_periph){ + switch(timer_periph) { case TIMER0: /* reset TIMER0 */ rcu_periph_reset_enable(RCU_TIMER0RST); @@ -122,12 +120,12 @@ void timer_deinit(uint32_t timer_periph) } /*! - \brief initialize TIMER init parameter struct with a default value + \brief initialize TIMER init parameter struct with a default value \param[in] initpara: init parameter struct \param[out] none \retval none */ -void timer_struct_para_init(timer_parameter_struct* initpara) +void timer_struct_para_init(timer_parameter_struct *initpara) { /* initialize the init parameter struct member with the default value */ initpara->prescaler = 0U; @@ -139,7 +137,7 @@ void timer_struct_para_init(timer_parameter_struct* initpara) } /*! - \brief initialize TIMER counter + \brief initialize TIMER counter \param[in] timer_periph: TIMERx(x=0..13) \param[in] initpara: init parameter struct prescaler: prescaler value of the counter clock,0~65535 @@ -151,15 +149,15 @@ void timer_struct_para_init(timer_parameter_struct* initpara) \param[out] none \retval none */ -void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) { /* configure the counter prescaler value */ TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; /* configure the counter direction and aligned mode */ if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph) - || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER7 == timer_periph)){ - TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM); + || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER7 == timer_periph)) { + TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM); TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; } @@ -167,13 +165,13 @@ void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) /* configure the autoreload value */ TIMER_CAR(timer_periph) = (uint32_t)initpara->period; - if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)){ + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)) { /* reset the CKDIV bit */ TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV; TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; } - if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { /* configure the repetition counter value */ TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; } @@ -183,7 +181,7 @@ void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) } /*! - \brief enable a TIMER + \brief enable a TIMER \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -194,7 +192,7 @@ void timer_enable(uint32_t timer_periph) } /*! - \brief disable a TIMER + \brief disable a TIMER \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -205,7 +203,7 @@ void timer_disable(uint32_t timer_periph) } /*! - \brief enable the auto reload shadow function + \brief enable the auto reload shadow function \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -216,7 +214,7 @@ void timer_auto_reload_shadow_enable(uint32_t timer_periph) } /*! - \brief disable the auto reload shadow function + \brief disable the auto reload shadow function \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -227,7 +225,7 @@ void timer_auto_reload_shadow_disable(uint32_t timer_periph) } /*! - \brief enable the update event + \brief enable the update event \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -238,7 +236,7 @@ void timer_update_event_enable(uint32_t timer_periph) } /*! - \brief disable the update event + \brief disable the update event \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval none @@ -249,7 +247,7 @@ void timer_update_event_disable(uint32_t timer_periph) } /*! - \brief set TIMER counter alignment mode + \brief set TIMER counter alignment mode \param[in] timer_periph: TIMERx(x=0..4,7) \param[in] aligned: only one parameter can be selected which is shown as below: @@ -267,7 +265,7 @@ void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) } /*! - \brief set TIMER counter up direction + \brief set TIMER counter up direction \param[in] timer_periph: TIMERx(x=0..4,7) \param[out] none \retval none @@ -278,7 +276,7 @@ void timer_counter_up_direction(uint32_t timer_periph) } /*! - \brief set TIMER counter down direction + \brief set TIMER counter down direction \param[in] timer_periph: TIMERx(x=0..4,7) \param[out] none \retval none @@ -289,7 +287,7 @@ void timer_counter_down_direction(uint32_t timer_periph) } /*! - \brief configure TIMER prescaler + \brief configure TIMER prescaler \param[in] timer_periph: TIMERx(x=0..13) \param[in] prescaler: prescaler value,0~65535 \param[in] pscreload: prescaler reload mode @@ -302,14 +300,14 @@ void timer_counter_down_direction(uint32_t timer_periph) void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload) { TIMER_PSC(timer_periph) = (uint32_t)prescaler; - - if(TIMER_PSC_RELOAD_NOW == pscreload){ + + if(TIMER_PSC_RELOAD_NOW == pscreload) { TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; } } /*! - \brief configure TIMER repetition register value + \brief configure TIMER repetition register value \param[in] timer_periph: TIMERx(x=0,7) \param[in] repetition: the counter repetition value,0~255 \param[out] none @@ -318,38 +316,38 @@ void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t p void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) { TIMER_CREP(timer_periph) = (uint32_t)repetition; -} - +} + /*! - \brief configure TIMER autoreload register value + \brief configure TIMER autoreload register value \param[in] timer_periph: TIMERx(x=0..13) \param[in] autoreload: the counter auto-reload value \param[out] none \retval none -*/ -void timer_autoreload_value_config(uint32_t timer_periph,uint32_t autoreload) +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint32_t autoreload) { TIMER_CAR(timer_periph) = (uint32_t)autoreload; } /*! - \brief configure TIMER counter register value + \brief configure TIMER counter register value \param[in] timer_periph: TIMERx(x=0..13) \param[in] counter: the counter value,0~65535 \param[out] none \retval none -*/ -void timer_counter_value_config(uint32_t timer_periph , uint32_t counter) +*/ +void timer_counter_value_config(uint32_t timer_periph, uint32_t counter) { TIMER_CNT(timer_periph) = (uint32_t)counter; } /*! - \brief read TIMER counter value + \brief read TIMER counter value \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval counter value -*/ +*/ uint32_t timer_counter_read(uint32_t timer_periph) { uint32_t count_value = 0U; @@ -358,11 +356,11 @@ uint32_t timer_counter_read(uint32_t timer_periph) } /*! - \brief read TIMER prescaler value + \brief read TIMER prescaler value \param[in] timer_periph: TIMERx(x=0..13) \param[out] none \retval prescaler register value -*/ +*/ uint16_t timer_prescaler_read(uint32_t timer_periph) { uint16_t prescaler_value = 0U; @@ -371,7 +369,7 @@ uint16_t timer_prescaler_read(uint32_t timer_periph) } /*! - \brief configure TIMER single pulse mode + \brief configure TIMER single pulse mode \param[in] timer_periph: TIMERx(x=0..8,11) \param[in] spmode: only one parameter can be selected which is shown as below: @@ -382,17 +380,17 @@ uint16_t timer_prescaler_read(uint32_t timer_periph) */ void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) { - if(TIMER_SP_MODE_SINGLE == spmode){ + if(TIMER_SP_MODE_SINGLE == spmode) { TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; - }else if(TIMER_SP_MODE_REPETITIVE == spmode){ + } else if(TIMER_SP_MODE_REPETITIVE == spmode) { TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); - }else{ + } else { /* illegal parameters */ } } /*! - \brief configure TIMER update source + \brief configure TIMER update source \param[in] timer_periph: TIMERx(x=0..13) \param[in] update: only one parameter can be selected which is shown as below: @@ -403,161 +401,17 @@ void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) */ void timer_update_source_config(uint32_t timer_periph, uint32_t update) { - if(TIMER_UPDATE_SRC_REGULAR == update){ + if(TIMER_UPDATE_SRC_REGULAR == update) { TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; - }else if(TIMER_UPDATE_SRC_GLOBAL == update){ + } else if(TIMER_UPDATE_SRC_GLOBAL == update) { TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; - }else{ + } else { /* illegal parameters */ } } /*! - \brief enable the TIMER interrupt - \param[in] timer_periph: please refer to the following parameters - \param[in] interrupt: timer interrupt enable source - only one parameter can be selected which is shown as below: - \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) - \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) - \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) - \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) - \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) - \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) - \param[out] none - \retval none -*/ -void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) -{ - TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; -} - -/*! - \brief disable the TIMER interrupt - \param[in] timer_periph: please refer to the following parameters - \param[in] interrupt: timer interrupt source enable - only one parameter can be selected which is shown as below: - \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) - \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) - \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) - \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) - \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) - \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) - \param[out] none - \retval none -*/ -void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) -{ - TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); -} - -/*! - \brief get timer interrupt flag - \param[in] timer_periph: please refer to the following parameters - \param[in] interrupt: the timer interrupt bits - only one parameter can be selected which is shown as below: - \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) - \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) - \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) - \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) - \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) - \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) - \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) -{ - uint32_t val; - val = (TIMER_DMAINTEN(timer_periph) & interrupt); - if((RESET != (TIMER_INTF(timer_periph) & interrupt) ) && (RESET != val)){ - return SET; - }else{ - return RESET; - } -} - -/*! - \brief clear TIMER interrupt flag - \param[in] timer_periph: please refer to the following parameters - \param[in] interrupt: the timer interrupt bits - only one parameter can be selected which is shown as below: - \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) - \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) - \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) - \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) - \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) - \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) - \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) - \param[out] none - \retval none -*/ -void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) -{ - TIMER_INTF(timer_periph) = (~(uint32_t)interrupt); -} - -/*! - \brief get TIMER flags - \param[in] timer_periph: please refer to the following parameters - \param[in] flag: the timer interrupt flags - only one parameter can be selected which is shown as below: - \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) - \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) - \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) - \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) - \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) - \arg TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) - \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7) - \param[out] none - \retval FlagStatus: SET or RESET -*/ -FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) -{ - if(RESET != (TIMER_INTF(timer_periph) & flag)){ - return SET; - }else{ - return RESET; - } -} - -/*! - \brief clear TIMER flags - \param[in] timer_periph: please refer to the following parameters - \param[in] flag: the timer interrupt flags - only one parameter can be selected which is shown as below: - \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) - \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) - \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) - \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) - \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) - \arg TIMER_FLAG_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) - \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) - \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) - \arg TIMER_FLAG_CH3OF: channel 3 overcapture flag,TIMERx(x=0..4,7) - \param[out] none - \retval none -*/ -void timer_flag_clear(uint32_t timer_periph, uint32_t flag) -{ - TIMER_INTF(timer_periph) = (~(uint32_t)flag); -} - -/*! - \brief enable the TIMER DMA + \brief enable the TIMER DMA \param[in] timer_periph: please refer to the following parameters \param[in] dma: specify which DMA to enable one or more parameters can be selected which is shown as below: @@ -573,11 +427,11 @@ void timer_flag_clear(uint32_t timer_periph, uint32_t flag) */ void timer_dma_enable(uint32_t timer_periph, uint16_t dma) { - TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; } /*! - \brief disable the TIMER DMA + \brief disable the TIMER DMA \param[in] timer_periph: please refer to the following parameters \param[in] dma: specify which DMA to disable one or more parameters can be selected which are shown as below: @@ -593,32 +447,32 @@ void timer_dma_enable(uint32_t timer_periph, uint16_t dma) */ void timer_dma_disable(uint32_t timer_periph, uint16_t dma) { - TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); } /*! - \brief channel DMA request source selection + \brief channel DMA request source selection \param[in] timer_periph: TIMERx(x=0..4,7) \param[in] dma_request: channel DMA request source selection only one parameter can be selected which is shown as below: \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs - \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs \param[out] none \retval none */ void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request) { - if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request) { TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; - }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + } else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request) { TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; - }else{ + } else { /* illegal parameters */ } } /*! - \brief configure the TIMER DMA transfer + \brief configure the TIMER DMA transfer \param[in] timer_periph: please refer to the following parameters \param[in] dma_baseaddr: only one parameter can be selected which is shown as below: @@ -655,16 +509,16 @@ void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uin } /*! - \brief software generate events + \brief software generate events \param[in] timer_periph: please refer to the following parameters \param[in] event: the timer software event generation sources one or more parameters can be selected which are shown as below: \arg TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0..13) - \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0..4,7..13) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0..4,7..13) \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation,TIMERx(x=0..4,7,8,11) - \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0..4,7) - \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0..4,7) - \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation,TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation,TIMERx(x=0,7) \arg TIMER_EVENT_SRC_TRGG: trigger event generation,TIMERx(x=0..4,7,8,11) \arg TIMER_EVENT_SRC_BRKG: break event generation,TIMERx(x=0,7) \param[out] none @@ -676,12 +530,12 @@ void timer_event_software_generate(uint32_t timer_periph, uint16_t event) } /*! - \brief initialize TIMER break parameter struct with a default value + \brief initialize TIMER break parameter struct \param[in] breakpara: TIMER break parameter struct \param[out] none \retval none */ -void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +void timer_break_struct_para_init(timer_break_parameter_struct *breakpara) { /* initialize the break parameter struct member with the default value */ breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; @@ -694,7 +548,7 @@ void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) } /*! - \brief configure TIMER break function + \brief configure TIMER break function \param[in] timer_periph: TIMERx(x=0,7) \param[in] breakpara: TIMER break parameter struct runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE @@ -707,19 +561,19 @@ void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) \param[out] none \retval none */ -void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara) +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara) { - TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate))| - ((uint32_t)(breakpara->ideloffstate))| - ((uint32_t)(breakpara->deadtime))| - ((uint32_t)(breakpara->breakpolarity))| + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate)) | + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->breakpolarity)) | ((uint32_t)(breakpara->outputautostate)) | - ((uint32_t)(breakpara->protectmode))| + ((uint32_t)(breakpara->protectmode)) | ((uint32_t)(breakpara->breakstate))) ; } /*! - \brief enable TIMER break function + \brief enable TIMER break function \param[in] timer_periph: TIMERx(x=0,7) \param[out] none \retval none @@ -730,7 +584,7 @@ void timer_break_enable(uint32_t timer_periph) } /*! - \brief disable TIMER break function + \brief disable TIMER break function \param[in] timer_periph: TIMERx(x=0,7) \param[out] none \retval none @@ -741,7 +595,7 @@ void timer_break_disable(uint32_t timer_periph) } /*! - \brief enable TIMER output automatic function + \brief enable TIMER output automatic function \param[in] timer_periph: TIMERx(x=0,7) \param[out] none \retval none @@ -752,7 +606,7 @@ void timer_automatic_output_enable(uint32_t timer_periph) } /*! - \brief disable TIMER output automatic function + \brief disable TIMER output automatic function \param[in] timer_periph: TIMERx(x=0,7) \param[out] none \retval none @@ -763,7 +617,7 @@ void timer_automatic_output_disable(uint32_t timer_periph) } /*! - \brief configure TIMER primary output function + \brief configure TIMER primary output function \param[in] timer_periph: TIMERx(x=0,7) \param[in] newvalue: ENABLE or DISABLE \param[out] none @@ -771,57 +625,57 @@ void timer_automatic_output_disable(uint32_t timer_periph) */ void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue) { - if(ENABLE == newvalue){ + if(ENABLE == newvalue) { TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; - }else{ + } else { TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); } } /*! - \brief enable or disable channel capture/compare control shadow register + \brief enable or disable channel capture/compare control shadow register \param[in] timer_periph: TIMERx(x=0,7) - \param[in] newvalue: ENABLE or DISABLE + \param[in] newvalue: ENABLE or DISABLE \param[out] none \retval none */ void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) { - if(ENABLE == newvalue){ + if(ENABLE == newvalue) { TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; - }else{ + } else { TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); } } /*! - \brief configure TIMER channel control shadow register update control + \brief configure TIMER channel control shadow register update control \param[in] timer_periph: TIMERx(x=0,7) \param[in] ccuctl: channel control shadow register update control only one parameter can be selected which is shown as below: \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set - \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs \param[out] none \retval none -*/ +*/ void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) { - if(TIMER_UPDATECTL_CCU == ccuctl){ + if(TIMER_UPDATECTL_CCU == ccuctl) { TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); - }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + } else if(TIMER_UPDATECTL_CCUTRI == ccuctl) { TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; - }else{ + } else { /* illegal parameters */ } } /*! - \brief initialize TIMER channel output parameter struct with a default value + \brief initialize TIMER channel output parameter struct with a default value \param[in] ocpara: TIMER channel n output parameter struct \param[out] none \retval none */ -void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara) { /* initialize the channel output parameter struct member with the default value */ ocpara->outputstate = (uint16_t)TIMER_CCX_DISABLE; @@ -833,7 +687,7 @@ void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) } /*! - \brief configure TIMER channel output function + \brief configure TIMER channel output function \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: @@ -851,9 +705,9 @@ void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) \param[out] none \retval none */ -void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: /* reset the CH0EN bit */ @@ -866,7 +720,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ /* set the CH0P bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; - if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { /* reset the CH0NEN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); /* set the CH0NEN bit */ @@ -897,7 +751,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ /* set the CH1P bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U); - if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { /* reset the CH1NEN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); /* set the CH1NEN bit */ @@ -928,7 +782,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ /* set the CH2P bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U); - if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { /* reset the CH2NEN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); /* set the CH2NEN bit */ @@ -950,7 +804,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ /* configure TIMER_CH_3 */ case TIMER_CH_3: /* reset the CH3EN bit */ - TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; /* set the CH3EN bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 12U); @@ -959,7 +813,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ /* set the CH3P bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U); - if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)){ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { /* reset the ISO3 bit */ TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); /* set the ISO3 bit */ @@ -972,7 +826,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ } /*! - \brief configure TIMER channel output compare mode + \brief configure TIMER channel output compare mode \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: @@ -995,7 +849,7 @@ void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_ */ void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); @@ -1022,7 +876,7 @@ void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, u } /*! - \brief configure TIMER channel output pulse value + \brief configure TIMER channel output pulse value \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: @@ -1036,7 +890,7 @@ void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, u */ void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CH0CV(timer_periph) = (uint32_t)pulse; @@ -1051,7 +905,7 @@ void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t cha break; /* configure TIMER_CH_3 */ case TIMER_CH_3: - TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; break; default: break; @@ -1059,7 +913,7 @@ void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t cha } /*! - \brief configure TIMER channel output shadow function + \brief configure TIMER channel output shadow function \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: @@ -1076,7 +930,7 @@ void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t cha */ void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); @@ -1103,7 +957,7 @@ void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, } /*! - \brief configure TIMER channel output fast function + \brief configure TIMER channel output fast function \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: @@ -1120,7 +974,7 @@ void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, */ void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); @@ -1147,9 +1001,9 @@ void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, u } /*! - \brief configure TIMER channel output clear function + \brief configure TIMER channel output clear function \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7)) @@ -1164,7 +1018,7 @@ void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, u */ void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); @@ -1191,15 +1045,15 @@ void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, } /*! - \brief configure TIMER channel output polarity + \brief configure TIMER channel output polarity \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) - \param[in] ocpolarity: channel output polarity + \param[in] ocpolarity: channel output polarity only one parameter can be selected which is shown as below: \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high \arg TIMER_OC_POLARITY_LOW: channel output polarity is low @@ -1208,7 +1062,7 @@ void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, */ void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); @@ -1235,14 +1089,14 @@ void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channe } /*! - \brief configure TIMER channel complementary output polarity + \brief configure TIMER channel complementary output polarity \param[in] timer_periph: please refer to the following parameters \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) - \param[in] ocnpolarity: channel complementary output polarity + \param[in] ocnpolarity: channel complementary output polarity only one parameter can be selected which is shown as below: \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low @@ -1251,7 +1105,7 @@ void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channe */ void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); @@ -1273,9 +1127,9 @@ void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, u } /*! - \brief configure TIMER channel enable state + \brief configure TIMER channel enable state \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) @@ -1283,14 +1137,14 @@ void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, u \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) \param[in] state: TIMER channel enable state only one parameter can be selected which is shown as below: - \arg TIMER_CCX_ENABLE: channel enable - \arg TIMER_CCX_DISABLE: channel disable + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable \param[out] none \retval none */ void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); @@ -1317,23 +1171,23 @@ void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, } /*! - \brief configure TIMER channel complementary output enable state + \brief configure TIMER channel complementary output enable state \param[in] timer_periph: TIMERx(x=0,7) - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0 \arg TIMER_CH_1: TIMER channel1 \arg TIMER_CH_2: TIMER channel2 \param[in] ocnstate: TIMER channel complementary output enable state only one parameter can be selected which is shown as below: - \arg TIMER_CCXN_ENABLE: channel complementary enable - \arg TIMER_CCXN_DISABLE: channel complementary disable + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable \param[out] none \retval none */ void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); @@ -1355,12 +1209,12 @@ void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint } /*! - \brief initialize TIMER channel input parameter struct with a default value + \brief initialize TIMER channel input parameter struct \param[in] icpara: TIMER channel intput parameter struct \param[out] none \retval none */ -void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) +void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara) { /* initialize the channel input parameter struct member with the default value */ icpara->icpolarity = TIMER_IC_POLARITY_RISING; @@ -1370,9 +1224,9 @@ void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) } /*! - \brief configure TIMER input capture parameter + \brief configure TIMER input capture parameter \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) @@ -1386,9 +1240,9 @@ void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) \param[out] none \retval none */ -void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic_parameter_struct* icpara) +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: /* reset the CH0EN bit */ @@ -1407,7 +1261,7 @@ void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic /* set the CH0EN bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; break; - + /* configure TIMER_CH_1 */ case TIMER_CH_1: /* reset the CH1EN bit */ @@ -1432,7 +1286,7 @@ void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); /* reset the CH2P and CH2NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_CH2NP)); TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); /* reset the CH2MS bit */ @@ -1474,9 +1328,9 @@ void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic } /*! - \brief configure TIMER channel input capture prescaler value + \brief configure TIMER channel input capture prescaler value \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) @@ -1493,7 +1347,7 @@ void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic */ void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) { - switch(channel){ + switch(channel) { /* configure TIMER_CH_0 */ case TIMER_CH_0: TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); @@ -1520,9 +1374,9 @@ void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_ } /*! - \brief read TIMER channel capture compare register value + \brief read TIMER channel capture compare register value \param[in] timer_periph: please refer to the following parameters - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) @@ -1535,7 +1389,7 @@ uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16 { uint32_t count_value = 0U; - switch(channel){ + switch(channel) { /* read TIMER channel 0 capture compare register value */ case TIMER_CH_0: count_value = TIMER_CH0CV(timer_periph); @@ -1559,9 +1413,9 @@ uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16 } /*! - \brief configure TIMER input pwm capture function + \brief configure TIMER input pwm capture function \param[in] timer_periph: TIMERx(x=0..4,7,8,11) - \param[in] channel: + \param[in] channel: only one parameter can be selected which is shown as below: \arg TIMER_CH_0: TIMER channel0 \arg TIMER_CH_1: TIMER channel1 @@ -1573,30 +1427,30 @@ uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16 \param[out] none \retval none */ -void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm) { uint16_t icpolarity = 0x0U; uint16_t icselection = 0x0U; /* Set channel input polarity */ - if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity) { icpolarity = TIMER_IC_POLARITY_FALLING; - }else{ + } else { icpolarity = TIMER_IC_POLARITY_RISING; } /* Set channel input mode selection */ - if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection) { icselection = TIMER_IC_SELECTION_INDIRECTTI; - }else{ + } else { icselection = TIMER_IC_SELECTION_DIRECTTI; } - if(TIMER_CH_0 == channel){ + if(TIMER_CH_0 == channel) { /* reset the CH0EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); /* reset the CH0P and CH0NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); /* set the CH0P and CH0NP bits */ TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); /* reset the CH0MS bit */ @@ -1610,12 +1464,12 @@ void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, tim /* set the CH0EN bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; /* configure TIMER channel input capture prescaler value */ - timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(icpwm->icprescaler)); + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); /* reset the CH1EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); /* reset the CH1P and CH1NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); /* set the CH1P and CH1NP bits */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4U); /* reset the CH1MS bit */ @@ -1629,12 +1483,12 @@ void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, tim /* set the CH1EN bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; /* configure TIMER channel input capture prescaler value */ - timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(icpwm->icprescaler)); - }else{ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + } else { /* reset the CH1EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); /* reset the CH1P and CH1NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); /* set the CH1P and CH1NP bits */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U); /* reset the CH1MS bit */ @@ -1653,7 +1507,7 @@ void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, tim /* reset the CH0EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); /* reset the CH0P and CH0NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); /* set the CH0P and CH0NP bits */ TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; /* reset the CH0MS bit */ @@ -1672,9 +1526,9 @@ void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, tim } /*! - \brief configure TIMER hall sensor mode + \brief configure TIMER hall sensor mode \param[in] timer_periph: TIMERx(x=0..4,7) - \param[in] hallmode: + \param[in] hallmode: only one parameter can be selected which is shown as below: \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable @@ -1683,17 +1537,17 @@ void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, tim */ void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) { - if(TIMER_HALLINTERFACE_ENABLE == hallmode){ + if(TIMER_HALLINTERFACE_ENABLE == hallmode) { TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; - }else if(TIMER_HALLINTERFACE_DISABLE == hallmode){ + } else if(TIMER_HALLINTERFACE_DISABLE == hallmode) { TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; - }else{ + } else { /* illegal parameters */ } } /*! - \brief select TIMER input trigger source + \brief select TIMER input trigger source \param[in] timer_periph: please refer to the following parameters \param[in] intrigger: only one parameter can be selected which is shown as below: @@ -1715,7 +1569,7 @@ void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger } /*! - \brief select TIMER master mode output trigger source + \brief select TIMER master mode output trigger source \param[in] timer_periph: TIMERx(x=0..7) \param[in] outrigger: only one parameter can be selected which is shown as below: @@ -1737,14 +1591,14 @@ void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t o } /*! - \brief select TIMER slave mode + \brief select TIMER slave mode \param[in] timer_periph: TIMERx(x=0..4,7,8,11) \param[in] slavemode: only one parameter can be selected which is shown as below: \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable(TIMERx(x=0..4,7,8,11)) - \arg TIMER_ENCODER_MODE0: encoder mode 0(TIMERx(x=0..4,7)) - \arg TIMER_ENCODER_MODE1: encoder mode 1(TIMERx(x=0..4,7)) - \arg TIMER_ENCODER_MODE2: encoder mode 2(TIMERx(x=0..4,7)) + \arg TIMER_QUAD_DECODER_MODE0: quadrature decoder mode 0(TIMERx(x=0..4,7)) + \arg TIMER_QUAD_DECODER_MODE1: quadrature decoder mode 1(TIMERx(x=0..4,7)) + \arg TIMER_QUAD_DECODER_MODE2: quadrature decoder mode 2(TIMERx(x=0..4,7)) \arg TIMER_SLAVE_MODE_RESTART: restart mode(TIMERx(x=0..4,7,8,11)) \arg TIMER_SLAVE_MODE_PAUSE: pause mode(TIMERx(x=0..4,7,8,11)) \arg TIMER_SLAVE_MODE_EVENT: event mode(TIMERx(x=0..4,7,8,11)) @@ -1761,7 +1615,7 @@ void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) } /*! - \brief configure TIMER master slave mode + \brief configure TIMER master slave mode \param[in] timer_periph: TIMERx(x=0..4,7,8,11) \param[in] masterslave: only one parameter can be selected which is shown as below: @@ -1769,20 +1623,20 @@ void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable \param[out] none \retval none -*/ +*/ void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) { - if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave){ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave) { TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; - }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave){ + } else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave) { TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; - }else{ + } else { /* illegal parameters */ } } /*! - \brief configure TIMER external trigger input + \brief configure TIMER external trigger input \param[in] timer_periph: TIMERx(x=0..4,7) \param[in] extprescaler: only one parameter can be selected which is shown as below: @@ -1807,14 +1661,14 @@ void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, } /*! - \brief configure TIMER quadrature decoder mode - \param[in] timer_periph: TIMERx(x=0..4,7,8,11) - \param[in] decomode: + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] decomode: only one parameter can be selected which is shown as below: - \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level - \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level - \arg TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input - \param[in] ic0polarity: + \arg TIMER_QUAD_DECODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_QUAD_DECODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_QUAD_DECODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: only one parameter can be selected which is shown as below: \arg TIMER_IC_POLARITY_RISING: capture rising edge \arg TIMER_IC_POLARITY_FALLING: capture falling edge @@ -1826,21 +1680,21 @@ void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, \retval none */ void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, - uint16_t ic0polarity, uint16_t ic1polarity) + uint16_t ic0polarity, uint16_t ic1polarity) { TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; - TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS))); - TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); - TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity|((uint32_t)ic1polarity << 4U)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity | ((uint32_t)ic1polarity << 4U)); } /*! - \brief configure TIMER internal clock mode + \brief configure TIMER internal clock mode \param[in] timer_periph: TIMERx(x=0..4,7,8,11) \param[out] none \retval none @@ -1851,9 +1705,9 @@ void timer_internal_clock_config(uint32_t timer_periph) } /*! - \brief configure TIMER the internal trigger as external clock input + \brief configure TIMER the internal trigger as external clock input \param[in] timer_periph: TIMERx(x=0..4,7,8,11) - \param[in] intrigger: + \param[in] intrigger: only one parameter can be selected which is shown as below: \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0 \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1 @@ -1870,14 +1724,14 @@ void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint } /*! - \brief configure TIMER the external trigger as external clock input + \brief configure TIMER the external trigger as external clock input \param[in] timer_periph: TIMERx(x=0..4,7,8,11) - \param[in] extrigger: + \param[in] extrigger: only one parameter can be selected which is shown as below: \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 - \param[in] extpolarity: + \param[in] extpolarity: only one parameter can be selected which is shown as below: \arg TIMER_IC_POLARITY_RISING: active high or rising edge active \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active @@ -1886,13 +1740,13 @@ void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint \retval none */ void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, - uint16_t extpolarity, uint32_t extfilter) + uint16_t extpolarity, uint32_t extfilter) { - if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger) { /* reset the CH1EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); /* reset the CH1NP bit */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); /* set the CH1NP bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); /* reset the CH1MS bit */ @@ -1905,11 +1759,11 @@ void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 12U); /* set the CH1EN bit */ TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; - }else{ + } else { /* reset the CH0EN bit */ TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); /* reset the CH0P and CH0NP bits */ - TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); /* set the CH0P and CH0NP bits */ TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; /* reset the CH0MS bit */ @@ -1924,7 +1778,7 @@ void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; } /* select TIMER input trigger source */ - timer_input_trigger_source_select(timer_periph,extrigger); + timer_input_trigger_source_select(timer_periph, extrigger); /* reset the SMC bit */ TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); /* set the SMC bit */ @@ -1932,15 +1786,15 @@ void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint } /*! - \brief configure TIMER the external clock mode0 + \brief configure TIMER the external clock mode0 \param[in] timer_periph: TIMERx(x=0..4,7,8,11) - \param[in] extprescaler: + \param[in] extprescaler: only one parameter can be selected which is shown as below: \arg TIMER_EXT_TRI_PSC_OFF: no divided \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 - \param[in] extpolarity: + \param[in] extpolarity: only one parameter can be selected which is shown as below: \arg TIMER_ETP_FALLING: active low or falling edge active \arg TIMER_ETP_RISING: active high or rising edge active @@ -1961,15 +1815,15 @@ void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extpresca } /*! - \brief configure TIMER the external clock mode1 + \brief configure TIMER the external clock mode1 \param[in] timer_periph: TIMERx(x=0..4,7) - \param[in] extprescaler: + \param[in] extprescaler: only one parameter can be selected which is shown as below: \arg TIMER_EXT_TRI_PSC_OFF: no divided \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 - \param[in] extpolarity: + \param[in] extpolarity: only one parameter can be selected which is shown as below: \arg TIMER_ETP_FALLING: active low or falling edge active \arg TIMER_ETP_RISING: active high or rising edge active @@ -1987,7 +1841,7 @@ void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extpresca } /*! - \brief disable TIMER the external clock mode1 + \brief disable TIMER the external clock mode1 \param[in] timer_periph: TIMERx(x=0..4,7) \param[out] none \retval none @@ -1998,9 +1852,9 @@ void timer_external_clock_mode1_disable(uint32_t timer_periph) } /*! - \brief configure TIMER channel remap function + \brief configure TIMER channel remap function \param[in] timer_periph: TIMERx(x=1,4,10) - \param[in] remap: + \param[in] remap: only one parameter can be selected which is shown as below: \arg TIMER1_ITI1_RMP_TIMER7_TRGO: timer1 internal trigger input1 remap to TIMER7_TRGO \arg TIMER1_ITI1_RMP_ETHERNET_PTP: timer1 internal trigger input1 remap to ethernet PTP @@ -2009,7 +1863,7 @@ void timer_external_clock_mode1_disable(uint32_t timer_periph) \arg TIMER4_CI3_RMP_GPIO: timer4 channel 3 input remap to GPIO pin \arg TIMER4_CI3_RMP_IRC32K: timer4 channel 3 input remap to IRC32K \arg TIMER4_CI3_RMP_LXTAL: timer4 channel 3 input remap to LXTAL - \arg TIMER4_CI3_RMP_RTC_WAKEUP_INT: timer4 channel 3 input remap to RTC wakeup interrupt + \arg TIMER4_CI3_RMP_RTC_WAKEUP_INT: timer4 channel 3 input remap to RTC wakeup interrupt \arg TIMER10_ITI1_RMP_GPIO: timer10 internal trigger input1 remap based on GPIO setting \arg TIMER10_ITI1_RMP_RTC_HXTAL_DIV: timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) \param[out] none @@ -2021,9 +1875,9 @@ void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) } /*! - \brief configure TIMER write CHxVAL register selection + \brief configure TIMER write CHxVAL register selection \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) - \param[in] ccsel: + \param[in] ccsel: only one parameter can be selected which is shown as below: \arg TIMER_CHVSEL_DISABLE: no effect \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored @@ -2032,17 +1886,17 @@ void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) */ void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) { - if(TIMER_CHVSEL_ENABLE == ccsel){ + if(TIMER_CHVSEL_ENABLE == ccsel) { TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; - }else if(TIMER_CHVSEL_DISABLE == ccsel){ + } else if(TIMER_CHVSEL_DISABLE == ccsel) { TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL; - }else{ + } else { /* illegal parameters */ } } /*! - \brief configure TIMER output value selection + \brief configure TIMER output value selection \param[in] timer_periph: TIMERx(x=0,7) \param[in] outsel: only one parameter can be selected which is shown as below: @@ -2053,11 +1907,155 @@ void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) */ void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) { - if(TIMER_OUTSEL_ENABLE == outsel){ + if(TIMER_OUTSEL_ENABLE == outsel) { TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; - }else if(TIMER_OUTSEL_DISABLE == outsel){ + } else if(TIMER_OUTSEL_DISABLE == outsel) { TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; - }else{ + } else { /* illegal parameters */ } } + +/*! + \brief get TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0..4,7) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt enable source + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt source enable + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & interrupt); + if((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)interrupt); +} diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c index 437df1c..18ed843 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c @@ -1,36 +1,34 @@ /*! \file gd32f4xx_tli.c \brief TLI driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. */ @@ -40,7 +38,7 @@ OF SUCH DAMAGE. #define TLI_OPAQUE_VALUE 0x000000FFU /*! - \brief deinitialize TLI registers + \brief deinitialize TLI registers \param[in] none \param[out] none \retval none @@ -52,7 +50,7 @@ void tli_deinit(void) } /*! - \brief initialize the parameters of TLI parameter structure with the default values, it is suggested + \brief initialize the parameters of TLI parameter structure with the default values, it is suggested that call this function after a tli_parameter_struct structure is defined \param[in] none \param[out] tli_struct: the data needed to initialize TLI @@ -67,9 +65,9 @@ void tli_deinit(void) backcolor_red: background value red backcolor_green: background value green backcolor_blue: background value blue - signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGHT - signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGHT - signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT + signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGH + signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGH + signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGH signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI \retval none */ @@ -94,7 +92,7 @@ void tli_struct_para_init(tli_parameter_struct *tli_struct) } /*! - \brief initialize TLI display timing parameters + \brief initialize TLI display timing parameters \param[in] tli_struct: the data needed to initialize TLI synpsz_vpsz: size of the vertical synchronous pulse synpsz_hpsz: size of the horizontal synchronous pulse @@ -107,9 +105,9 @@ void tli_struct_para_init(tli_parameter_struct *tli_struct) backcolor_red: background value red backcolor_green: background value green backcolor_blue: background value blue - signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGHT - signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGHT - signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT + signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGH + signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGH + signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGH signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI \param[out] none \retval none @@ -117,28 +115,28 @@ void tli_struct_para_init(tli_parameter_struct *tli_struct) void tli_init(tli_parameter_struct *tli_struct) { /* synchronous pulse size configuration */ - TLI_SPSZ &= ~(TLI_SPSZ_VPSZ|TLI_SPSZ_HPSZ); - TLI_SPSZ = (uint32_t)((uint32_t)tli_struct->synpsz_vpsz|((uint32_t)tli_struct->synpsz_hpsz<<16U)); + TLI_SPSZ &= ~(TLI_SPSZ_VPSZ | TLI_SPSZ_HPSZ); + TLI_SPSZ = (uint32_t)((uint32_t)tli_struct->synpsz_vpsz | ((uint32_t)tli_struct->synpsz_hpsz << 16U)); /* back-porch size configuration */ - TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ|TLI_BPSZ_HBPSZ); - TLI_BPSZ = (uint32_t)((uint32_t)tli_struct->backpsz_vbpsz|((uint32_t)tli_struct->backpsz_hbpsz<<16U)); - /* active size configuration */ - TLI_ASZ &= ~(TLI_ASZ_VASZ|TLI_ASZ_HASZ); - TLI_ASZ = (tli_struct->activesz_vasz|(tli_struct->activesz_hasz<<16U)); - /* total size configuration */ - TLI_TSZ &= ~(TLI_TSZ_VTSZ|TLI_TSZ_HTSZ); - TLI_TSZ = (tli_struct->totalsz_vtsz|(tli_struct->totalsz_htsz<<16U)); - /* background color configuration */ - TLI_BGC &= ~(TLI_BGC_BVB|(TLI_BGC_BVG)|(TLI_BGC_BVR)); - TLI_BGC = (tli_struct->backcolor_blue|(tli_struct->backcolor_green<<8U)|(tli_struct->backcolor_red<<16U)); - TLI_CTL &= ~(TLI_CTL_HPPS|TLI_CTL_VPPS|TLI_CTL_DEPS|TLI_CTL_CLKPS); - TLI_CTL |= (tli_struct->signalpolarity_hs|tli_struct->signalpolarity_vs|\ - tli_struct->signalpolarity_de|tli_struct->signalpolarity_pixelck); + TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ | TLI_BPSZ_HBPSZ); + TLI_BPSZ = (uint32_t)((uint32_t)tli_struct->backpsz_vbpsz | ((uint32_t)tli_struct->backpsz_hbpsz << 16U)); + /* active size configuration */ + TLI_ASZ &= ~(TLI_ASZ_VASZ | TLI_ASZ_HASZ); + TLI_ASZ = (tli_struct->activesz_vasz | (tli_struct->activesz_hasz << 16U)); + /* total size configuration */ + TLI_TSZ &= ~(TLI_TSZ_VTSZ | TLI_TSZ_HTSZ); + TLI_TSZ = (tli_struct->totalsz_vtsz | (tli_struct->totalsz_htsz << 16U)); + /* background color configuration */ + TLI_BGC &= ~(TLI_BGC_BVB | (TLI_BGC_BVG) | (TLI_BGC_BVR)); + TLI_BGC = (tli_struct->backcolor_blue | (tli_struct->backcolor_green << 8U) | (tli_struct->backcolor_red << 16U)); + TLI_CTL &= ~(TLI_CTL_HPPS | TLI_CTL_VPPS | TLI_CTL_DEPS | TLI_CTL_CLKPS); + TLI_CTL |= (tli_struct->signalpolarity_hs | tli_struct->signalpolarity_vs | \ + tli_struct->signalpolarity_de | tli_struct->signalpolarity_pixelck); } /*! - \brief configure TLI dither function + \brief configure TLI dither function \param[in] dither_stat only one parameter can be selected which is shown as below: \arg TLI_DITHER_ENABLE @@ -148,15 +146,15 @@ void tli_init(tli_parameter_struct *tli_struct) */ void tli_dither_config(uint8_t dither_stat) { - if(TLI_DITHER_ENABLE == dither_stat){ + if(TLI_DITHER_ENABLE == dither_stat) { TLI_CTL |= TLI_CTL_DFEN; - }else{ + } else { TLI_CTL &= ~(TLI_CTL_DFEN); } } /*! - \brief enable TLI + \brief enable TLI \param[in] none \param[out] none \retval none @@ -167,7 +165,7 @@ void tli_enable(void) } /*! - \brief disable TLI + \brief disable TLI \param[in] none \param[out] none \retval none @@ -178,7 +176,7 @@ void tli_disable(void) } /*! - \brief configure TLI reload mode + \brief configure TLI reload mode \param[in] reload_mod only one parameter can be selected which is shown as below: \arg TLI_FRAME_BLANK_RELOAD_EN @@ -188,23 +186,23 @@ void tli_disable(void) */ void tli_reload_config(uint8_t reload_mod) { - if(TLI_FRAME_BLANK_RELOAD_EN == reload_mod){ + if(TLI_FRAME_BLANK_RELOAD_EN == reload_mod) { /* the layer configuration will be reloaded at frame blank */ TLI_RL |= TLI_RL_FBR; - }else{ + } else { /* the layer configuration will be reloaded after this bit sets */ TLI_RL |= TLI_RL_RQR; } } /*! - \brief initialize the parameters of TLI layer structure with the default values, it is suggested + \brief initialize the parameters of TLI layer structure with the default values, it is suggested that call this function after a tli_layer_parameter_struct structure is defined \param[in] none \param[out] layer_struct: TLI Layer parameter struct layer_window_rightpos: window right position layer_window_leftpos: window left position - layer_window_bottompos: window bottom position + layer_window_bottompos: window bottom position layer_window_toppos: window top position layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565, LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8, @@ -244,12 +242,12 @@ void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct) } /*! - \brief initialize TLI layer + \brief initialize TLI layer \param[in] layerx: LAYERx(x=0,1) \param[in] layer_struct: TLI Layer parameter struct layer_window_rightpos: window right position layer_window_leftpos: window left position - layer_window_bottompos: window bottom position + layer_window_bottompos: window bottom position layer_window_toppos: window top position layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565, LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8, @@ -268,14 +266,14 @@ void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct) \param[out] none \retval none */ -void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct) +void tli_layer_init(uint32_t layerx, tli_layer_parameter_struct *layer_struct) { /* configure layer window horizontal position */ - TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP)); - TLI_LxHPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_leftpos|((uint32_t)layer_struct->layer_window_rightpos<<16U)); + TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP | (TLI_LxHPOS_WRP)); + TLI_LxHPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_leftpos | ((uint32_t)layer_struct->layer_window_rightpos << 16U)); /* configure layer window vertical position */ - TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP)); - TLI_LxVPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_toppos|((uint32_t)layer_struct->layer_window_bottompos<<16U)); + TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP | (TLI_LxVPOS_WBP)); + TLI_LxVPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_toppos | ((uint32_t)layer_struct->layer_window_bottompos << 16U)); /* configure layer packeted pixel format */ TLI_LxPPF(layerx) &= ~(TLI_LxPPF_PPF); TLI_LxPPF(layerx) = layer_struct->layer_ppf; @@ -283,20 +281,20 @@ void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct) TLI_LxSA(layerx) &= ~(TLI_LxSA_SA); TLI_LxSA(layerx) = layer_struct->layer_sa; /* configure layer default color */ - TLI_LxDC(layerx) &= ~(TLI_LxDC_DCB|(TLI_LxDC_DCG)|(TLI_LxDC_DCR)|(TLI_LxDC_DCA)); - TLI_LxDC(layerx) = (uint32_t)((uint32_t)layer_struct->layer_default_blue|((uint32_t)layer_struct->layer_default_green<<8U) - |((uint32_t)layer_struct->layer_default_red<<16U) - |((uint32_t)layer_struct->layer_default_alpha<<24U)); + TLI_LxDC(layerx) &= ~(TLI_LxDC_DCB | (TLI_LxDC_DCG) | (TLI_LxDC_DCR) | (TLI_LxDC_DCA)); + TLI_LxDC(layerx) = (uint32_t)((uint32_t)layer_struct->layer_default_blue | ((uint32_t)layer_struct->layer_default_green << 8U) + | ((uint32_t)layer_struct->layer_default_red << 16U) + | ((uint32_t)layer_struct->layer_default_alpha << 24U)); /* configure layer alpha calculation factors */ - TLI_LxBLEND(layerx) &= ~(TLI_LxBLEND_ACF2|(TLI_LxBLEND_ACF1)); - TLI_LxBLEND(layerx) = ((layer_struct->layer_acf2)|(layer_struct->layer_acf1)); + TLI_LxBLEND(layerx) &= ~(TLI_LxBLEND_ACF2 | (TLI_LxBLEND_ACF1)); + TLI_LxBLEND(layerx) = ((layer_struct->layer_acf2) | (layer_struct->layer_acf1)); /* configure layer frame buffer base address */ TLI_LxFBADDR(layerx) &= ~(TLI_LxFBADDR_FBADD); TLI_LxFBADDR(layerx) = (layer_struct->layer_frame_bufaddr); /* configure layer frame line length */ - TLI_LxFLLEN(layerx) &= ~(TLI_LxFLLEN_FLL|(TLI_LxFLLEN_STDOFF)); - TLI_LxFLLEN(layerx) = (uint32_t)((uint32_t)layer_struct->layer_frame_line_length|((uint32_t)layer_struct->layer_frame_buf_stride_offset<<16U)); + TLI_LxFLLEN(layerx) &= ~(TLI_LxFLLEN_FLL | (TLI_LxFLLEN_STDOFF)); + TLI_LxFLLEN(layerx) = (uint32_t)((uint32_t)layer_struct->layer_frame_line_length | ((uint32_t)layer_struct->layer_frame_buf_stride_offset << 16U)); /* configure layer frame total line number */ TLI_LxFTLN(layerx) &= ~(TLI_LxFTLN_FTLN); TLI_LxFTLN(layerx) = (uint32_t)(layer_struct->layer_frame_total_line_number); @@ -304,56 +302,56 @@ void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct) } /*! - \brief reconfigure window position + \brief reconfigure window position \param[in] layerx: LAYERx(x=0,1) \param[in] offset_x: new horizontal offset \param[in] offset_y: new vertical offset \param[out] none \retval none */ -void tli_layer_window_offset_modify(uint32_t layerx,uint16_t offset_x,uint16_t offset_y) +void tli_layer_window_offset_modify(uint32_t layerx, uint16_t offset_x, uint16_t offset_y) { /* configure window start position */ uint32_t layer_ppf, line_num, hstart, vstart; uint32_t line_length = 0U; - TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP|(TLI_LxHPOS_WRP)); - TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP|(TLI_LxVPOS_WBP)); - hstart = (uint32_t)offset_x+(((TLI_BPSZ & TLI_BPSZ_HBPSZ)>>16U)+1U); - vstart = (uint32_t)offset_y+((TLI_BPSZ & TLI_BPSZ_VBPSZ)+1U); + TLI_LxHPOS(layerx) &= ~(TLI_LxHPOS_WLP | (TLI_LxHPOS_WRP)); + TLI_LxVPOS(layerx) &= ~(TLI_LxVPOS_WTP | (TLI_LxVPOS_WBP)); + hstart = (uint32_t)offset_x + (((TLI_BPSZ & TLI_BPSZ_HBPSZ) >> 16U) + 1U); + vstart = (uint32_t)offset_y + ((TLI_BPSZ & TLI_BPSZ_VBPSZ) + 1U); line_num = (TLI_LxFTLN(layerx) & TLI_LxFTLN_FTLN); layer_ppf = (TLI_LxPPF(layerx) & TLI_LxPPF_PPF); /* the bytes of a line equal TLI_LxFLLEN_FLL bits value minus 3 */ - switch(layer_ppf){ + switch(layer_ppf) { case LAYER_PPF_ARGB8888: /* each pixel includes 4bytes, when pixel format is ARGB8888 */ - line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/4U); + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL) - 3U) / 4U); break; case LAYER_PPF_RGB888: /* each pixel includes 3bytes, when pixel format is RGB888 */ - line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/3U); + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL) - 3U) / 3U); break; case LAYER_PPF_RGB565: case LAYER_PPF_ARGB1555: case LAYER_PPF_ARGB4444: case LAYER_PPF_AL88: /* each pixel includes 2bytes, when pixel format is RGB565,ARG1555,ARGB4444 or AL88 */ - line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)/2U); + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL) - 3U) / 2U); break; case LAYER_PPF_L8: case LAYER_PPF_AL44: /* each pixel includes 1byte, when pixel format is L8 or AL44 */ - line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL)-3U)); + line_length = (((TLI_LxFLLEN(layerx) & TLI_LxFLLEN_FLL) - 3U)); break; default: break; } /* reconfigure window position */ - TLI_LxHPOS(layerx) = (hstart|((hstart+line_length-1U)<<16U)); - TLI_LxVPOS(layerx) = (vstart|((vstart+line_num-1U)<<16U)); + TLI_LxHPOS(layerx) = (hstart | ((hstart + line_length - 1U) << 16U)); + TLI_LxVPOS(layerx) = (vstart | ((vstart + line_num - 1U) << 16U)); } /*! - \brief initialize the parameters of TLI layer LUT structure with the default values, it is suggested + \brief initialize the parameters of TLI layer LUT structure with the default values, it is suggested that call this function after a tli_layer_lut_parameter_struct structure is defined \param[in] none \param[out] lut_struct: TLI layer LUT parameter struct @@ -373,7 +371,7 @@ void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct) } /*! - \brief initialize TLI layer LUT + \brief initialize TLI layer LUT \param[in] layerx: LAYERx(x=0,1) \param[in] lut_struct: TLI layer LUT parameter struct layer_table_addr: look up table write address @@ -383,29 +381,29 @@ void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct) \param[out] none \retval none */ -void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct) +void tli_lut_init(uint32_t layerx, tli_layer_lut_parameter_struct *lut_struct) { - TLI_LxLUT(layerx) = (uint32_t)(((uint32_t)lut_struct->layer_lut_channel_blue)|((uint32_t)lut_struct->layer_lut_channel_green<<8U) - |((uint32_t)lut_struct->layer_lut_channel_red<<16U - |((uint32_t)lut_struct->layer_table_addr<<24U))); + TLI_LxLUT(layerx) = (uint32_t)(((uint32_t)lut_struct->layer_lut_channel_blue) | ((uint32_t)lut_struct->layer_lut_channel_green << 8U) + | ((uint32_t)lut_struct->layer_lut_channel_red << 16U + | ((uint32_t)lut_struct->layer_table_addr << 24U))); } /*! - \brief initialize TLI layer color key + \brief initialize TLI layer color key \param[in] layerx: LAYERx(x=0,1) \param[in] redkey: color key red - \param[in] greenkey: color key green + \param[in] greenkey: color key green \param[in] bluekey: color key blue \param[out] none \retval none */ -void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey) +void tli_color_key_init(uint32_t layerx, uint8_t redkey, uint8_t greenkey, uint8_t bluekey) { - TLI_LxCKEY(layerx) = (((uint32_t)bluekey)|((uint32_t)greenkey<<8U)|((uint32_t)redkey<<16U)); + TLI_LxCKEY(layerx) = (((uint32_t)bluekey) | ((uint32_t)greenkey << 8U) | ((uint32_t)redkey << 16U)); } /*! - \brief enable TLI layer + \brief enable TLI layer \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -416,7 +414,7 @@ void tli_layer_enable(uint32_t layerx) } /*! - \brief disable TLI layer + \brief disable TLI layer \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -427,7 +425,7 @@ void tli_layer_disable(uint32_t layerx) } /*! - \brief enable TLI layer color keying + \brief enable TLI layer color keying \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -438,7 +436,7 @@ void tli_color_key_enable(uint32_t layerx) } /*! - \brief disable TLI layer color keying + \brief disable TLI layer color keying \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -449,7 +447,7 @@ void tli_color_key_disable(uint32_t layerx) } /*! - \brief enable TLI layer LUT + \brief enable TLI layer LUT \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -460,7 +458,7 @@ void tli_lut_enable(uint32_t layerx) } /*! - \brief disable TLI layer LUT + \brief disable TLI layer LUT \param[in] layerx: LAYERx(x=0,1) \param[out] none \retval none @@ -471,8 +469,8 @@ void tli_lut_disable(uint32_t layerx) } /*! - \brief set line mark value - \param[in] line_num: line number + \brief set line mark value + \param[in] line_num: line number \param[out] none \retval none */ @@ -483,7 +481,7 @@ void tli_line_mark_set(uint16_t line_num) } /*! - \brief get current displayed position + \brief get current displayed position \param[in] none \param[out] none \retval position of current pixel @@ -494,13 +492,13 @@ uint32_t tli_current_pos_get(void) } /*! - \brief enable TLI interrupt + \brief enable TLI interrupt \param[in] int_flag: TLI interrupt flags one or more parameters can be selected which are shown as below: - \arg TLI_INT_LM: line mark interrupt - \arg TLI_INT_FE: FIFO error interrupt - \arg TLI_INT_TE: transaction error interrupt - \arg TLI_INT_LCR: layer configuration reloaded interrupt + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt \param[out] none \retval none */ @@ -510,13 +508,13 @@ void tli_interrupt_enable(uint32_t int_flag) } /*! - \brief disable TLI interrupt + \brief disable TLI interrupt \param[in] int_flag: TLI interrupt flags one or more parameters can be selected which are shown as below: - \arg TLI_INT_LM: line mark interrupt - \arg TLI_INT_FE: FIFO error interrupt - \arg TLI_INT_TE: transaction error interrupt - \arg TLI_INT_LCR: layer configuration reloaded interrupt + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt \param[out] none \retval none */ @@ -526,7 +524,7 @@ void tli_interrupt_disable(uint32_t int_flag) } /*! - \brief get TLI interrupt flag + \brief get TLI interrupt flag \param[in] int_flag: TLI interrupt flags one or more parameters can be selected which are shown as below: \arg TLI_INT_FLAG_LM: line mark interrupt flag @@ -540,9 +538,10 @@ FlagStatus tli_interrupt_flag_get(uint32_t int_flag) { uint32_t state; state = TLI_INTF; - if(state & int_flag){ + if(state & int_flag) { state = TLI_INTEN; - if(state & int_flag){ + /* check whether the corresponding bit in TLI_INTEN is set or not */ + if(state & int_flag) { return SET; } } @@ -550,7 +549,7 @@ FlagStatus tli_interrupt_flag_get(uint32_t int_flag) } /*! - \brief clear TLI interrupt flag + \brief clear TLI interrupt flag \param[in] int_flag: TLI interrupt flags one or more parameters can be selected which are shown as below: \arg TLI_INT_FLAG_LM: line mark interrupt flag @@ -566,17 +565,17 @@ void tli_interrupt_flag_clear(uint32_t int_flag) } /*! - \brief get TLI flag or state in TLI_INTF register or TLI_STAT register + \brief get TLI flag or state in TLI_INTF register or TLI_STAT register \param[in] flag: TLI flags or states only one parameter can be selected which is shown as below: - \arg TLI_FLAG_VDE: current VDE state + \arg TLI_FLAG_VDE: current VDE state \arg TLI_FLAG_HDE: current HDE state \arg TLI_FLAG_VS: current VS status of the TLI \arg TLI_FLAG_HS: current HS status of the TLI \arg TLI_FLAG_LM: line mark interrupt flag \arg TLI_FLAG_FE: FIFO error interrupt flag - \arg TLI_FLAG_TE: transaction error interrupt flag - \arg TLI_FLAG_LCR: layer configuration reloaded interrupt flag + \arg TLI_FLAG_TE: transaction error interrupt flag + \arg TLI_FLAG_LCR: layer configuration reloaded interrupt flag \param[out] none \retval FlagStatus: SET or RESET */ @@ -584,14 +583,14 @@ FlagStatus tli_flag_get(uint32_t flag) { uint32_t stat; /* choose which register to get flag or state */ - if(flag >> 31U){ + if(flag >> 31U) { stat = TLI_INTF; - }else{ + } else { stat = TLI_STAT; } - if(flag & stat){ + if(flag & stat) { return SET; - }else{ + } else { return RESET; } } diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c index 040add4..502e97e 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c @@ -2,42 +2,40 @@ \file gd32f4xx_trng.c \brief TRNG driver - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_trng.h" /*! - \brief deinitialize the TRNG + \brief reset TRNG \param[in] none \param[out] none \retval none @@ -49,7 +47,7 @@ void trng_deinit(void) } /*! - \brief enable the TRNG interface + \brief enable TRNG \param[in] none \param[out] none \retval none @@ -60,7 +58,7 @@ void trng_enable(void) } /*! - \brief disable the TRNG interface + \brief disable TRNG \param[in] none \param[out] none \retval none @@ -71,10 +69,10 @@ void trng_disable(void) } /*! - \brief get the true random data + \brief get the true random data \param[in] none \param[out] none - \retval the generated random data + \retval uint32_t: 0x0-0xFFFFFFFF */ uint32_t trng_get_true_random_data(void) { @@ -82,70 +80,70 @@ uint32_t trng_get_true_random_data(void) } /*! - \brief enable the TRNG interrupt + \brief enable TRNG interrupt \param[in] none \param[out] none \retval none */ -void trng_interrupt_enable(void) +void trng_interrupt_enable(void) { - TRNG_CTL |= TRNG_CTL_IE; + TRNG_CTL |= TRNG_CTL_TRNGIE; } /*! - \brief disable the TRNG interrupt + \brief disable TRNG interrupt \param[in] none \param[out] none \retval none */ void trng_interrupt_disable(void) { - TRNG_CTL &= ~TRNG_CTL_IE; + TRNG_CTL &= ~TRNG_CTL_TRNGIE; } /*! - \brief get the trng status flags - \param[in] flag: trng status flag, refer to trng_flag_enum + \brief get TRNG flag status + \param[in] flag: TRNG flag only one parameter can be selected which is shown as below: - \arg TRNG_FLAG_DRDY: Random Data ready status - \arg TRNG_FLAG_CECS: Clock error current status - \arg TRNG_FLAG_SECS: Seed error current status + \arg TRNG_FLAG_DRDY: random Data ready status + \arg TRNG_FLAG_CECS: clock error current status + \arg TRNG_FLAG_SECS: seed error current status \param[out] none \retval FlagStatus: SET or RESET */ FlagStatus trng_flag_get(trng_flag_enum flag) { - if(RESET != (TRNG_STAT & flag)){ + if(RESET != (TRNG_STAT & flag)) { return SET; - }else{ + } else { return RESET; } } /*! - \brief get the trng interrupt flags - \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + \brief get TRNG interrupt flag status + \param[in] int_flag: TRNG interrupt flag only one parameter can be selected which is shown as below: \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag - \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \arg TRNG_INT_FLAG_SEIF: seed error interrupt flag \param[out] none \retval FlagStatus: SET or RESET */ FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag) { - if(RESET != (TRNG_STAT & int_flag)){ + if(RESET != (TRNG_STAT & int_flag)) { return SET; - }else{ + } else { return RESET; } } /*! - \brief clear the trng interrupt flags - \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + \brief clear TRNG interrupt flag status + \param[in] int_flag: TRNG interrupt flag only one parameter can be selected which is shown as below: \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag - \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \arg TRNG_INT_FLAG_SEIF: seed error interrupt flag \param[out] none \retval none */ diff --git a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c index 35ab1fd..e69999e 100644 --- a/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c +++ b/lib-gd32/gd32f4xx/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c @@ -1,40 +1,37 @@ /*! \file gd32f4xx_usart.c \brief USART driver - - \version 2016-08-15, V1.0.0, firmware for GD32F4xx - \version 2018-12-12, V2.0.0, firmware for GD32F4xx - \version 2020-09-30, V2.1.0, firmware for GD32F4xx + + \version 2023-06-25, V3.1.0, firmware for GD32F4xx */ /* - Copyright (c) 2020, GigaDevice Semiconductor Inc. + Copyright (c) 2023, GigaDevice Semiconductor Inc. - Redistribution and use in source and binary forms, with or without modification, + 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 + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + 2. Redistributions in binary form 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 the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "gd32f4xx_usart.h" /* USART register bit offset */ @@ -43,14 +40,14 @@ OF SUCH DAMAGE. #define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */ /*! - \brief reset USART/UART + \brief reset USART/UART \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) \param[out] none \retval none */ void usart_deinit(uint32_t usart_periph) { - switch(usart_periph){ + switch(usart_periph) { case USART0: rcu_periph_reset_enable(RCU_USART0RST); rcu_periph_reset_disable(RCU_USART0RST); @@ -94,52 +91,52 @@ void usart_deinit(uint32_t usart_periph) \param[in] baudval: baud rate value \param[out] none \retval none -*/ +*/ void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) { - uint32_t uclk=0U, intdiv=0U, fradiv=0U, udiv=0U; - switch(usart_periph){ - /* get clock frequency */ + uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U; + switch(usart_periph) { + /* get clock frequency */ case USART0: - uclk=rcu_clock_freq_get(CK_APB2); - break; + uclk = rcu_clock_freq_get(CK_APB2); + break; case USART5: - uclk=rcu_clock_freq_get(CK_APB2); - break; + uclk = rcu_clock_freq_get(CK_APB2); + break; case USART1: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; case USART2: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; case UART3: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; case UART4: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; case UART6: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; case UART7: - uclk=rcu_clock_freq_get(CK_APB1); - break; + uclk = rcu_clock_freq_get(CK_APB1); + break; default: - break; + break; } - if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD) { /* when oversampling by 8, configure the value of USART_BAUD */ - udiv = ((2U*uclk) + baudval/2U)/baudval; + udiv = ((2U * uclk) + baudval / 2U) / baudval; intdiv = udiv & 0xfff0U; - fradiv = (udiv>>1U) & 0x7U; + fradiv = (udiv >> 1U) & 0x7U; USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); - }else{ + } else { /* when oversampling by 16, configure the value of USART_BAUD */ - udiv = (uclk+baudval/2U)/baudval; + udiv = (uclk + baudval / 2U) / baudval; intdiv = udiv & 0xfff0U; fradiv = udiv & 0xfU; USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); - } + } } /*! @@ -148,7 +145,7 @@ void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) \param[in] paritycfg: configure USART parity only one parameter can be selected which is shown as below: \arg USART_PM_NONE: no parity - \arg USART_PM_EVEN: even parity + \arg USART_PM_EVEN: even parity \arg USART_PM_ODD: odd parity \param[out] none \retval none @@ -157,7 +154,7 @@ void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) { /* clear USART_CTL0 PM,PCEN Bits */ USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); - /* configure USART parity mode */ + /* configure USART parity mode */ USART_CTL0(usart_periph) |= paritycfg ; } @@ -194,7 +191,7 @@ void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) { /* clear USART_CTL1 STB bits */ - USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; /* configure USART stop bits */ USART_CTL1(usart_periph) |= stblen; } @@ -233,7 +230,7 @@ void usart_disable(uint32_t usart_periph) void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) { uint32_t ctl = 0U; - + ctl = USART_CTL0(usart_periph); ctl &= ~USART_CTL0_TEN; ctl |= txconfig; @@ -254,7 +251,7 @@ void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) { uint32_t ctl = 0U; - + ctl = USART_CTL0(usart_periph); ctl &= ~USART_CTL0_REN; ctl |= rxconfig; @@ -275,12 +272,12 @@ void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) { uint32_t ctl = 0U; - + ctl = USART_CTL3(usart_periph); - ctl &= ~(USART_CTL3_MSBF); + ctl &= ~(USART_CTL3_MSBF); ctl |= msbf; /* configure data transmitted/received mode */ - USART_CTL3(usart_periph) = ctl; + USART_CTL3(usart_periph) = ctl; } /*! @@ -299,8 +296,8 @@ void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) */ void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) { - /* inverted or not the specified siginal */ - switch(invertpara){ + /* inverted or not the specified siginal */ + switch(invertpara) { case USART_DINV_ENABLE: USART_CTL3(usart_periph) |= USART_CTL3_DINV; break; @@ -325,7 +322,7 @@ void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) } /*! - \brief configure the USART oversample mode + \brief configure the USART oversample mode \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) \param[in] oversamp: oversample value only one parameter can be selected which is shown as below: @@ -353,7 +350,7 @@ void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) */ void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm) { - USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); USART_CTL2(usart_periph) |= obsm; } @@ -395,13 +392,13 @@ void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rti /*! \brief USART transmit data function \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) - \param[in] data: data of transmission + \param[in] data: data of transmission \param[out] none \retval none */ -void usart_data_transmit(uint32_t usart_periph, uint32_t data) +void usart_data_transmit(uint32_t usart_periph, uint16_t data) { - USART_DATA(usart_periph) = ((uint16_t)USART_DATA_DATA & data); + USART_DATA(usart_periph) = USART_DATA_DATA & (uint32_t)data; } /*! @@ -425,7 +422,7 @@ uint16_t usart_data_receive(uint32_t usart_periph) void usart_address_config(uint32_t usart_periph, uint8_t addr) { USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); - USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (uint32_t)addr); } /*! @@ -473,7 +470,7 @@ void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod) \retval none */ void usart_lin_mode_enable(uint32_t usart_periph) -{ +{ USART_CTL1(usart_periph) |= USART_CTL1_LMEN; } @@ -484,7 +481,7 @@ void usart_lin_mode_enable(uint32_t usart_periph) \retval none */ void usart_lin_mode_disable(uint32_t usart_periph) -{ +{ USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); } @@ -522,7 +519,7 @@ void usart_send_break(uint32_t usart_periph) \retval none */ void usart_halfduplex_enable(uint32_t usart_periph) -{ +{ USART_CTL2(usart_periph) |= USART_CTL2_HDEN; } @@ -533,7 +530,7 @@ void usart_halfduplex_enable(uint32_t usart_periph) \retval none */ void usart_halfduplex_disable(uint32_t usart_periph) -{ +{ USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); } @@ -564,30 +561,23 @@ void usart_synchronous_clock_disable(uint32_t usart_periph) \param[in] usart_periph: USARTx(x=0,1,2,5) \param[in] clen: CK length only one parameter can be selected which is shown as below: - \arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame + \arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame \arg USART_CLEN_EN: there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame \param[in] cph: clock phase only one parameter can be selected which is shown as below: - \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_1CK: first clock transition is the first data capture edge \arg USART_CPH_2CK: second clock transition is the first data capture edge \param[in] cpl: clock polarity only one parameter can be selected which is shown as below: - \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_LOW: steady low value on CK pin \arg USART_CPL_HIGH: steady high value on CK pin \param[out] none \retval none */ void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) { - uint32_t ctl = 0U; - - /* read USART_CTL1 register */ - ctl = USART_CTL1(usart_periph); - ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); - /* set CK length, CK phase, CK polarity */ - ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl); - - USART_CTL1(usart_periph) = ctl; + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl); } /*! @@ -597,10 +587,10 @@ void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32 \param[out] none \retval none */ -void usart_guard_time_config(uint32_t usart_periph,uint32_t guat) +void usart_guard_time_config(uint32_t usart_periph, uint8_t guat) { USART_GP(usart_periph) &= ~(USART_GP_GUAT); - USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat)< + /** * LEDs */ @@ -75,35 +77,32 @@ */ #define I2C0_REMAP -#if defined (I2C0_REMAP) -# define I2C_REMAP GPIO_I2C0_REMAP -#endif +#define I2C_REMAP GPIO_I2C0_REMAP #define I2C_PERIPH I2C0_PERIPH -#define I2C_RCU_CLK I2C0_RCU_CLK -#define I2C_GPIO_SCL_PORT I2C0_SCL_GPIOx -#define I2C_GPIO_SCL_CLK I2C0_SCL_RCU_GPIOx -#define I2C_GPIO_SDA_PORT I2C0_SDA_GPIOx -#define I2C_GPIO_SDA_CLK I2C0_SDA_RCU_GPIOx -#define I2C_SCL_PIN I2C0_SCL_GPIO_PINx -#define I2C_SDA_PIN I2C0_SDA_GPIO_PINx +#define I2C_RCU_I2Cx I2C0_RCU_I2C0 +#define I2C_GPIO_AFx I2C0_GPIO_AFx +#define I2C_SCL_RCU_GPIOx I2C0_SCL_RCU_GPIOx +#define I2C_SCL_GPIOx I2C0_SCL_GPIOx +#define I2C_SCL_GPIO_PINx I2C0_SCL_GPIO_PINx +#define I2C_SDA_RCU_GPIOx I2C0_SDA_RCU_GPIOx +#define I2C_SDA_GPIOx I2C0_SDA_GPIOx +#define I2C_SDA_GPIO_PINx I2C0_SDA_GPIO_PINx /** * SPI */ -#if defined (SPI2_REMAP) -# define SPI_REMAP SPI2_REMAP_GPIO -#endif #define SPI_PERIPH SPI2_PERIPH +#define SPI_RCU_SPIx SPI2_RCU_SPI2 +#define SPI_RCU_GPIOx SPI2_RCU_GPIOx +#define SPI_GPIO_AFx SPI2_GPIO_AFx +#define SPI_GPIOx SPI2_GPIOx +#define SPI_SCK_GPIO_PINx SPI2_SCK_GPIO_PINx +#define SPI_MISO_GPIO_PINx SPI2_MISO_GPIO_PINx +#define SPI_MOSI_GPIO_PINx SPI2_MOSI_GPIO_PINx #define SPI_NSS_GPIOx SPI2_NSS_GPIOx #define SPI_NSS_RCU_GPIOx SPI2_NSS_RCU_GPIOx #define SPI_NSS_GPIO_PINx SPI2_NSS_GPIO_PINx -#define SPI_RCU_CLK SPI2_RCU_CLK -#define SPI_GPIOx SPI2_GPIOx -#define SPI_RCU_GPIOx SPI2_RCU_GPIOx -#define SPI_SCK_PIN SPI2_SCK_GPIO_PINx -#define SPI_MISO_PIN SPI2_MISO_GPIO_PINx -#define SPI_MOSI_PIN SPI2_MOSI_GPIO_PINx #define SPI_DMAx SPI2_DMAx #define SPI_DMA_CHx SPI2_TX_DMA_CHx #define SPI_DMA_SUBPERIx SPI2_TX_DMA_SUBPERIx @@ -118,6 +117,7 @@ /** * Panel LEDs */ + #ifdef __cplusplus namespace hal { namespace panelled { @@ -143,9 +143,9 @@ static constexpr uint32_t PORT_A_TX = 0; * SPI flash */ -#define SPI_FLASH_CS_GPIOx SPI_NSS_GPIOx -#define SPI_FLASH_CS_RCU_GPIOx SPI_NSS_RCU_GPIOx -#define SPI_FLASH_CS_GPIO_PINx SPI_NSS_GPIO_PINx +#define SPI_FLASH_CS_RCU_GPIOx SPI_NSS_RCU_GPIOx +#define SPI_FLASH_CS_GPIOx SPI_NSS_GPIOx +#define SPI_FLASH_CS_GPIO_PINx SPI_NSS_GPIO_PINx /** * EXT PHY @@ -179,14 +179,28 @@ static constexpr uint32_t PORT_A_TX = 0; #define GD32_BOARD_LED3 GD32_PORT_TO_GPIO(GD32_GPIO_PORTC, 3) #define GD32_BOARD_STATUS_LED GD32_BOARD_LED1 +/** + * LCD + */ + +#define DISPLAYTIMEOUT_GPIO GD32_PORT_TO_GPIO(GD32_GPIO_PORTC, 13) // KEY2 + +/** + * Pixel DMX + */ + +#define PIXELDMXSTARTSTOP_GPIO GD32_PORT_TO_GPIO(GD32_GPIO_PORTC, 2) // LED2 + /** * SPI LCD */ -#define SPI_LCD_DC_PIN GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 11) -#define SPI_LCD_BL_PIN GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 12) -#define SPI_LCD_CS_PIN GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 13) #define SPI_LCD_RST_PIN GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 14) +#define SPI_LCD_DC_GPIO GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 11) +#define SPI_LCD_BL_GPIO GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 12) +#if defined(SPI_LCD_HAVE_CS_GPIO) +# define SPI_LCD_CS_GPIO GD32_PORT_TO_GPIO(GD32_GPIO_PORTA, 13) +#endif #include "gpio_header.h" diff --git a/lib-gd32/include/board/logic_analyzer.h b/lib-gd32/include/board/logic_analyzer.h index e3bc5fa..9c2ab50 100644 --- a/lib-gd32/include/board/logic_analyzer.h +++ b/lib-gd32/include/board/logic_analyzer.h @@ -2,7 +2,7 @@ * @file logic_analyzer.h * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,60 +26,31 @@ #ifndef BOARD_LOGIC_ANALYZER_H_ #define BOARD_LOGIC_ANALYZER_H_ -#if defined (BOARD_GD32F207C_EVAL) -# define LOGIC_ANALYZER_CH0_GPIO_PINx GPIO_PIN_0 -# define LOGIC_ANALYZER_CH1_GPIO_PINx GPIO_PIN_1 -# define LOGIC_ANALYZER_CH2_GPIO_PINx GPIO_PIN_7 -//#define LOGIC_ANALYZER_CH3_GPIO_PINx -//#define LOGIC_ANALYZER_CH4_GPIO_PINx -//#define LOGIC_ANALYZER_CH5_GPIO_PINx -//#define LOGIC_ANALYZER_CH6_GPIO_PINx -//#define LOGIC_ANALYZER_CH7_GPIO_PINx - -# define LOGIC_ANALYZER_CH0_GPIOx GPIOE -# define LOGIC_ANALYZER_CH1_GPIOx GPIOE -# define LOGIC_ANALYZER_CH2_GPIOx GPIOD -# define LOGIC_ANALYZER_CH3_GPIOx -# define LOGIC_ANALYZER_CH4_GPIOx -# define LOGIC_ANALYZER_CH5_GPIOx -# define LOGIC_ANALYZER_CH6_GPIOx -# define LOGIC_ANALYZER_CH7_GPIOx - -# define LOGIC_ANALYZER_CH0_RCU_GPIOx RCU_GPIOE -# define LOGIC_ANALYZER_CH1_RCU_GPIOx RCU_GPIOE -# define LOGIC_ANALYZER_CH2_RCU_GPIOx RCU_GPIOD -# define LOGIC_ANALYZER_CH3_RCU_GPIOx -# define LOGIC_ANALYZER_CH4_RCU_GPIOx -# define LOGIC_ANALYZER_CH5_RCU_GPIOx -# define LOGIC_ANALYZER_CH6_RCU_GPIOx -# define LOGIC_ANALYZER_CH7_RCU_GPIOx -#else -# define LOGIC_ANALYZER_CH0_GPIO_PINx GPIO_PIN_8 // PC8 -# define LOGIC_ANALYZER_CH1_GPIO_PINx GPIO_PIN_9 // PC9 -# define LOGIC_ANALYZER_CH2_GPIO_PINx GPIO_PIN_13 // PC13 -# define LOGIC_ANALYZER_CH3_GPIO_PINx GPIO_PIN_4 // PA4 -# define LOGIC_ANALYZER_CH4_GPIO_PINx GPIO_PIN_5 // PA5 -# define LOGIC_ANALYZER_CH5_GPIO_PINx GPIO_PIN_13 // PA13 -//# define LOGIC_ANALYZER_CH6_GPIO_PINx GPIO_PIN_ -//# define LOGIC_ANALYZER_CH7_GPIO_PINx GPIO_PIN_ - -# define LOGIC_ANALYZER_CH0_GPIOx GPIOC -# define LOGIC_ANALYZER_CH1_GPIOx GPIOC -# define LOGIC_ANALYZER_CH2_GPIOx GPIOC -# define LOGIC_ANALYZER_CH3_GPIOx GPIOA -# define LOGIC_ANALYZER_CH4_GPIOx GPIOA -# define LOGIC_ANALYZER_CH5_GPIOx GPIOA -# define LOGIC_ANALYZER_CH6_GPIOx GPIO -# define LOGIC_ANALYZER_CH7_GPIOx GPIO - -# define LOGIC_ANALYZER_CH0_RCU_GPIOx RCU_GPIOC -# define LOGIC_ANALYZER_CH1_RCU_GPIOx RCU_GPIOC -# define LOGIC_ANALYZER_CH2_RCU_GPIOx RCU_GPIOC -# define LOGIC_ANALYZER_CH3_RCU_GPIOx RCU_GPIOA -# define LOGIC_ANALYZER_CH4_RCU_GPIOx RCU_GPIOA -# define LOGIC_ANALYZER_CH5_RCU_GPIOx RCU_GPIOA -# define LOGIC_ANALYZER_CH6_RCU_GPIOx RCU_GPIO -# define LOGIC_ANALYZER_CH7_RCU_GPIOx RCU_GPIO -#endif +#define LOGIC_ANALYZER_CH0_GPIO_PINx GPIO_PIN_3 +#define LOGIC_ANALYZER_CH1_GPIO_PINx GPIO_PIN_4 +#define LOGIC_ANALYZER_CH2_GPIO_PINx GPIO_PIN_5 +#define LOGIC_ANALYZER_CH3_GPIO_PINx GPIO_PIN_8 +#define LOGIC_ANALYZER_CH4_GPIO_PINx GPIO_PIN_9 +#define LOGIC_ANALYZER_CH5_GPIO_PINx GPIO_PIN_13 +#define LOGIC_ANALYZER_CH6_GPIO_PINx GPIO_PIN_11 +#define LOGIC_ANALYZER_CH7_GPIO_PINx GPIO_PIN_15 + +#define LOGIC_ANALYZER_CH0_GPIOx GPIOB +#define LOGIC_ANALYZER_CH1_GPIOx GPIOB +#define LOGIC_ANALYZER_CH2_GPIOx GPIOB +#define LOGIC_ANALYZER_CH3_GPIOx GPIOC +#define LOGIC_ANALYZER_CH4_GPIOx GPIOC +#define LOGIC_ANALYZER_CH5_GPIOx GPIOC +#define LOGIC_ANALYZER_CH6_GPIOx GPIOA +#define LOGIC_ANALYZER_CH7_GPIOx GPIOA + +#define LOGIC_ANALYZER_CH0_RCU_GPIOx RCU_GPIOB +#define LOGIC_ANALYZER_CH1_RCU_GPIOx RCU_GPIOB +#define LOGIC_ANALYZER_CH2_RCU_GPIOx RCU_GPIOB +#define LOGIC_ANALYZER_CH3_RCU_GPIOx RCU_GPIOC +#define LOGIC_ANALYZER_CH4_RCU_GPIOx RCU_GPIOC +#define LOGIC_ANALYZER_CH5_RCU_GPIOx RCU_GPIOC +#define LOGIC_ANALYZER_CH6_RCU_GPIOx RCU_GPIOA +#define LOGIC_ANALYZER_CH7_RCU_GPIOx RCU_GPIOA #endif /* BOARD_LOGIC_ANALYZER_H_ */ diff --git a/lib-gd32/include/gd32.h b/lib-gd32/include/gd32.h index b13f5dc..c138dad 100644 --- a/lib-gd32/include/gd32.h +++ b/lib-gd32/include/gd32.h @@ -2,7 +2,7 @@ * @file gd32.h * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,17 +26,22 @@ #ifndef GD32_H_ #define GD32_H_ -#include +# include -#if !defined __cplusplus - void udelay(uint32_t us); -#else -# if !defined(GD32_UDELAY) -# define GD32_UDELAY +#ifdef __cplusplus +# if !defined(UDELAY) +# define UDELAY void udelay(uint32_t us, uint32_t offset = 0); # endif #endif +struct HwTimersSeconds { +#if !defined (CONFIG_ENET_ENABLE_PTP) + volatile uint32_t nTimeval; +#endif + volatile uint32_t nUptime; +}; + /* * Needed for GD32 Firmware and CMSIS */ @@ -45,25 +50,23 @@ #ifdef __cplusplus # pragma GCC diagnostic ignored "-Wold-style-cast" # pragma GCC diagnostic ignored "-Wuseless-cast" +# if __cplusplus > 201402 +// error: compound assignment with 'volatile'-qualified left operand is deprecated +# pragma GCC diagnostic ignored "-Wvolatile" +# endif extern "C" { #endif -#if defined (GD32F10X_HD) || defined (GD32F10X_CL) -# define GD32F10X +#if defined (GD32F10X_HD) || defined (GD32F10X_CL) # include "gd32f10x.h" -# include "gd32f10x_libopt.h" #elif defined (GD32F20X_CL) -# define GD32F20X # include "gd32f20x.h" -# include "gd32f20x_libopt.h" #elif defined (GD32F30X_HD) -# define GD32F30X # include "gd32f30x.h" -# include "gd32f30x_libopt.h" -#elif defined (GD32F407) || defined (GD32F450) -# define GD32F4XX +#elif defined (GD32F407) || defined (GD32F450) || defined (GD32F470) # include "gd32f4xx.h" -# include "gd32f4xx_libopt.h" +#elif defined (GD32H759) +# include "gd32h7xx.h" #else # error MCU is not supported #endif @@ -77,7 +80,7 @@ extern "C" { # define bkp_data_read bkp_read_data #endif -#if defined(GD32F4XX) && defined(__cplusplus) +#if (defined(GD32F4XX) || defined (GD32H7XX)) && defined(__cplusplus) typedef enum { BKP_DATA_0, @@ -87,6 +90,34 @@ void bkp_data_write(bkp_data_register_enum register_number, uint16_t data); uint16_t bkp_data_read(bkp_data_register_enum register_number); #endif +#if !(defined (GD32F4XX) || defined (GD32H7XX)) +#define GPIO_INIT +#endif + +#if defined (GD32H7XX) +# define GPIO_OSPEED GPIO_OSPEED_60MHZ +#else +# define GPIO_OSPEED GPIO_OSPEED_50MHZ +#endif + +#define GD32_PORT_TO_GPIO(p,n) ((p * 16) + n) +#define GD32_GPIO_TO_PORT(g) (uint8_t)(g / 16) +#define GD32_GPIO_TO_NUMBER(g) (uint8_t)(g - (16 * GD32_GPIO_TO_PORT(g))) + +typedef enum T_GD32_Port { + GD32_GPIO_PORTA = 0, + GD32_GPIO_PORTB, + GD32_GPIO_PORTC, + GD32_GPIO_PORTD, + GD32_GPIO_PORTE, + GD32_GPIO_PORTF, + GD32_GPIO_PORTG, + GD32_GPIO_PORTH, + GD32_GPIO_PORTI, + GD32_GPIO_PORTJ, + GD32_GPIO_PORTK +} GD32_Port_TypeDef; + #include "gd32_board.h" #endif /* GD32_H_ */ diff --git a/lib-gd32/include/gd32_adc.h b/lib-gd32/include/gd32_adc.h index d637dc6..fc66537 100644 --- a/lib-gd32/include/gd32_adc.h +++ b/lib-gd32/include/gd32_adc.h @@ -26,10 +26,10 @@ #ifndef GD32_ADC_H_ #define GD32_ADC_H_ -float gd32_adc_gettemp(void); -float gd32_adc_getvref(void); +float gd32_adc_gettemp(); +float gd32_adc_getvref(); #if defined (GD32F4XX) -float gd32_adc_getvbat(void); +float gd32_adc_getvbat(); #endif #ifdef __cplusplus diff --git a/lib-gd32/include/gd32_board.h b/lib-gd32/include/gd32_board.h index bb1ec55..f07b59e 100644 --- a/lib-gd32/include/gd32_board.h +++ b/lib-gd32/include/gd32_board.h @@ -2,7 +2,7 @@ * @file gd32_board.h * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,8 +46,14 @@ # include "board/gd32f450vi.h" #elif defined (BOARD_16X4U_PIXEL) # include "board/16x4u-pixel.h" +#elif defined (BOARD_GD32F470VG) +# include "board/gd32f470vg.h" #elif defined (BOARD_GD32F207C_EVAL) # include "board/gd32f207c_eval.h" +#elif defined (BOARD_GD32F470Z_EVAL) +# include "board/gd32f470z_eval.h" +#elif defined (BOARD_GD32H759I_EVAL) +# include "board/gd32h759i_eval.h" #elif defined (BOARD_BW_OPIDMX4) # include "board/bw_opidmx4.h" #elif defined (BOARD_DMX3) @@ -64,4 +70,22 @@ # error Configuration error #endif +#if defined (GD32H7XX) +# ifdef USE_ENET0 +# define ENETx ENET0 +# define RCU_ENET RCU_ENET0 +# define RCU_ENETTX RCU_ENET0TX +# define RCU_ENETRX RCU_ENET0RX +# elif USE_ENET1 +# define ENETx ENET1 +# define RCU_ENET RCU_ENET1 +# define RCU_ENETTX RCU_ENET1TX +# define RCU_ENETRX RCU_ENET1RX +# else +# error +# endif +#else +# define ENETx +#endif + #endif /* GD32_BOARD_H_ */ diff --git a/lib-gd32/include/gd32_dma.h b/lib-gd32/include/gd32_dma.h new file mode 100644 index 0000000..fbad893 --- /dev/null +++ b/lib-gd32/include/gd32_dma.h @@ -0,0 +1,225 @@ +/** + * @file gd32_dma.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GD32_DMA_H_ +#define GD32_DMA_H_ + +#include +#include + +#include "gd32.h" + +#if defined (GD32F4XX) || defined (GD32H7XX) +# define DMA_PARAMETER_STRUCT dma_single_data_parameter_struct +# define DMA_CHMADDR DMA_CHM0ADDR +# define DMA_MEMORY_TO_PERIPHERAL DMA_MEMORY_TO_PERIPH +# define DMA_PERIPHERAL_WIDTH_8BIT DMA_PERIPH_WIDTH_8BIT +# define dma_init dma_single_data_mode_init +# define dma_memory_to_memory_disable(x,y) +#else +# define DMA_PARAMETER_STRUCT dma_parameter_struct +#endif + +#if defined (GD32F10X) || defined (GD32F30X) +template +bool gd32_dma_interrupt_flag_get() { + uint32_t interrupt_enable = 0, interrupt_flag = 0; + + switch (flag) { + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE; + break; + default: + assert(0); + } + + return interrupt_flag && interrupt_enable; +} +#elif defined (GD32F20X) +template +bool gd32_dma_interrupt_flag_get() { + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + uint32_t gif_check = 0x0FU, gif_enable = 0x0EU; + + switch (flag) { + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE; + break; + case DMA_INT_FLAG_G: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(gif_check, channelx); + interrupt_flag = interrupt_flag >> ((channelx) * 4U); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & gif_enable; + break; + default: + assert(0); + } + + return (interrupt_flag && interrupt_enable); +} +#elif defined (GD32F4XX) || defined (GD32H7XX) +template +bool gd32_dma_interrupt_flag_get() { + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + if constexpr (channelx < DMA_CH4) { + switch (flag) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF0( dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx)); + interrupt_enable = (DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE); + break; + default: + assert(0); + break; + } + } else if constexpr (channelx <= DMA_CH7) { + constexpr uint32_t channel_flag_offset = static_cast(channelx) - 4; + switch (flag) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channel_flag_offset); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + default: + assert(0); + break; + } + } else { + assert(0); + } + + return (interrupt_flag && interrupt_enable); +} +#else +# error +#endif + +#if defined (GD32F10X) || defined (GD32F30X) || defined (GD32F20X) +template +void gd32_dma_interrupt_flag_clear() { + DMA_INTC(peripheral) |= DMA_FLAG_ADD(nFlag, channel); +} +#elif defined (GD32F4XX) || defined (GD32H7XX) +template +inline void gd32_dma_interrupt_flag_clear() { + if constexpr (channel < DMA_CH4) { + DMA_INTC0(peripheral) |= DMA_FLAG_ADD(nFlag, channel); + } else { + DMA_INTC1(peripheral) |= DMA_FLAG_ADD(nFlag, static_cast(channel) - 4U); + } +} +#else +# error +#endif + +#if defined (GD32F10X) || defined (GD32F30X) +template +void gd32_dma_interrupt_disable() { + if constexpr (DMA1 == peripheral) { + static_assert(channel <= DMA_CH4, "for DMA1, the channel is from DMA_CH0 to DMA_CH4"); + } + + DMA_CHCTL(peripheral, channel) &= static_cast(~nSource); +} +#elif defined (GD32F20X) +template +void gd32_dma_interrupt_disable() { + DMA_CHCTL(peripheral, channel) &= static_cast(~nSource); +} +#elif defined (GD32F4XX) +template +void gd32_dma_interrupt_disable() { + if constexpr (DMA_CHXFCTL_FEEIE != nSource) { + DMA_CHCTL(peripheral, channel) &= static_cast(~nSource); + } else { + DMA_CHFCTL(peripheral, channel) &= static_cast(~nSource); + } +} +#elif defined (GD32H7XX) +template +void gd32_dma_interrupt_disable() { + if constexpr (DMA_CHXFCTL_FEEIE != (DMA_CHXFCTL_FEEIE & nSource)) { + DMA_CHCTL(peripheral, channel) &= static_cast(~nSource); + } else { + DMA_CHFCTL(peripheral, channel) &= static_cast(~DMA_CHXFCTL_FEEIE); + DMA_CHCTL(peripheral, channel) &= static_cast(~(nSource & (~DMA_CHXFCTL_FEEIE))); + } +} +#else +# error +#endif + +#endif /* GD32_DMA_H_ */ diff --git a/lib-gd32/include/gd32_dma_memcpy32.h b/lib-gd32/include/gd32_dma_memcpy32.h new file mode 100644 index 0000000..c7936c1 --- /dev/null +++ b/lib-gd32/include/gd32_dma_memcpy32.h @@ -0,0 +1,56 @@ +/* + * gd32_dma_memcpy32.h + */ + +#ifndef GD32_DMA_MEMCPY32_H_ +#define GD32_DMA_MEMCPY32_H_ + +#include +#include + +#include "gd32.h" + +namespace dma { +void memcpy32_init() ; + +inline void memcpy32(const void *pDestination, const void *pSource, const uint32_t nLength) { + assert((reinterpret_cast(pSource) & 0x3) == 0); + assert((reinterpret_cast(pDestination) & 0x3) == 0); + +#if !defined (GD32F4XX) + uint32_t dmaCHCTL = DMA_CHCTL(DMA0, DMA_CH3); + dmaCHCTL &= ~DMA_CHXCTL_CHEN; + DMA_CHCTL(DMA0, DMA_CH3) = dmaCHCTL; + + DMA_CHPADDR(DMA0, DMA_CH3) = reinterpret_cast(pSource); + DMA_CHMADDR(DMA0, DMA_CH3) = reinterpret_cast(pDestination); + DMA_CHCNT(DMA0, DMA_CH3) = (nLength & DMA_CHXCNT_CNT); + + dmaCHCTL |= DMA_CHXCTL_CHEN; + DMA_CHCTL(DMA0, DMA_CH3) = dmaCHCTL; +#else + uint32_t dmaCHCTL = DMA_CHCTL(DMA1, DMA_CH0); + dmaCHCTL &= ~DMA_CHXCTL_CHEN; + DMA_CHCTL(DMA1, DMA_CH0) = dmaCHCTL; + + DMA_INTC0(DMA1) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, DMA_CH0); + + DMA_CHM0ADDR(DMA1, DMA_CH0) = reinterpret_cast(pDestination); + DMA_CHPADDR(DMA1, DMA_CH0) = reinterpret_cast(pSource); + DMA_CHCNT(DMA1, DMA_CH0) = nLength; + + dmaCHCTL |= DMA_CHXCTL_CHEN; + DMA_CHCTL(DMA1, DMA_CH0) = dmaCHCTL; +#endif +} + +inline bool memcpy32_is_active() { +#if !defined (GD32F4XX) + return DMA_CHCNT(DMA0, DMA_CH3) != 0; +#else + return DMA_CHCNT(DMA1, DMA_CH0) != 0; +#endif +} +} // namespace dma + +#endif /* GD32_DMA_MEMCPY32_H_ */ diff --git a/lib-gd32/include/gd32_gpio.h b/lib-gd32/include/gd32_gpio.h index 7591f93..71ec42c 100644 --- a/lib-gd32/include/gd32_gpio.h +++ b/lib-gd32/include/gd32_gpio.h @@ -2,7 +2,7 @@ * @file gd32_gpio.h * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,20 +27,7 @@ #define GD32_GPIO_H_ #include - -#define GD32_PORT_TO_GPIO(p,n) ((p * 16) + n) -#define GD32_GPIO_TO_PORT(g) (uint8_t)(g / 16) -#define GD32_GPIO_TO_NUMBER(g) (uint8_t)(g - (16 * GD32_GPIO_TO_PORT(g))) - -typedef enum T_GD32_Port { - GD32_GPIO_PORTA = 0, - GD32_GPIO_PORTB, - GD32_GPIO_PORTC, - GD32_GPIO_PORTD, - GD32_GPIO_PORTE, - GD32_GPIO_PORTF, - GD32_GPIO_PORTG, -} GD32_Port_TypeDef; +#include #include "gd32.h" @@ -52,7 +39,7 @@ typedef enum T_GD32_Port { # define GPIO_PULL_DISABLE GPIO_MODE_IN_FLOATING # define GPIO_INT_CFG_NEG_EDGE EXTI_TRIG_FALLING # define GPIO_INT_CFG_BOTH EXTI_TRIG_BOTH -#elif defined (GD32F407) || defined (GD32F450) +#elif defined (GD32F407) || defined (GD32F450) || defined (GD32F470) || defined (GD32F470) || defined (GD32H759) # define GPIO_FSEL_OUTPUT GPIO_MODE_OUTPUT # define GPIO_FSEL_INPUT GPIO_MODE_INPUT # define GPIO_PULL_UP GPIO_PUPD_PULLUP @@ -60,7 +47,8 @@ typedef enum T_GD32_Port { # define GPIO_PULL_DISABLE GPIO_PUPD_NONE #endif -inline static void gpio_fsel(const uint32_t gpio_periph, const uint32_t pin, const uint32_t fsel) { +#ifdef __cplusplus +inline void gpio_fsel(const uint32_t gpio_periph, const uint32_t pin, const uint32_t fsel) { switch (gpio_periph) { case GPIOA: rcu_periph_clock_enable(RCU_GPIOA); @@ -80,11 +68,32 @@ inline static void gpio_fsel(const uint32_t gpio_periph, const uint32_t pin, con case GPIOF: rcu_periph_clock_enable(RCU_GPIOF); break; + case GPIOG: + rcu_periph_clock_enable(RCU_GPIOG); + break; +#if !(defined (GD32F10X) || defined (GD32F30X)) + case GPIOH: + rcu_periph_clock_enable(RCU_GPIOH); + break; +# if !defined (GD32H7XX) + case GPIOI: + rcu_periph_clock_enable(RCU_GPIOI); + break; +# endif +#endif +#if defined (GD32H7XX) + case GPIOJ: + rcu_periph_clock_enable(RCU_GPIOJ); + break; + case GPIOK: + rcu_periph_clock_enable(RCU_GPIOK); + break; +#endif default: break; } -#if defined (GD32F10X) || defined (GD32F20X) || defined (GD32F30X) +#if defined (GD32F10X) || defined (GD32F20X) || defined (GD32F30X) if (gpio_periph == GPIOA) { if ((pin == GPIO_PIN_13) || (pin == GPIO_PIN_14)) { rcu_periph_clock_enable(RCU_AF); @@ -93,10 +102,10 @@ inline static void gpio_fsel(const uint32_t gpio_periph, const uint32_t pin, con } gpio_init(gpio_periph, fsel, GPIO_OSPEED_50MHZ, pin); -#elif defined (GD32F4XX) +#elif defined (GD32F4XX) || defined (GD32H7XX) if (fsel == GPIO_FSEL_OUTPUT) { gpio_mode_set(gpio_periph, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pin); - gpio_output_options_set(gpio_periph, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, pin); + gpio_output_options_set(gpio_periph, GPIO_OTYPE_PP, GPIO_OSPEED, pin); } else { gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, pin); } @@ -105,31 +114,8 @@ inline static void gpio_fsel(const uint32_t gpio_periph, const uint32_t pin, con #endif } -inline static void gd32_gpio_fsel(const uint32_t gpio, const uint32_t fsel) { - const uint32_t gpio_periph = GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); - const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); - - gpio_fsel(gpio_periph, pin, fsel); -} - -inline static void gd32_gpio_pud(const uint32_t gpio, const uint32_t pud) { - const uint32_t gpio_periph = GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); - const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); - -#if defined (GD32F10X) || defined (GD32F20X) || defined (GD32F30X) - gpio_init(gpio_periph, pud, GPIO_OSPEED_50MHZ, pin); -#elif defined (GD32F4XX) - if (pud == GPIO_PULL_UP) { - gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, pin); - } else if (pud == GPIO_PULL_DOWN) { - gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, pin); - } else { - gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_NONE, pin); - } -#endif -} - -inline static void gd32_gpio_int_cfg(const uint32_t gpio, const uint32_t trig_type) { +#if !defined (GD32H7XX) +inline void gd32_gpio_int_cfg(const uint32_t gpio, const uint32_t trig_type) { const uint32_t linex = BIT(GD32_GPIO_TO_NUMBER(gpio)); switch(trig_type){ @@ -158,22 +144,66 @@ inline static void gd32_gpio_int_cfg(const uint32_t gpio, const uint32_t trig_ty syscfg_exti_line_config(output_port, output_pin); #endif } +#endif -inline static void gd32_gpio_clr(const uint32_t gpio) { - const uint32_t gpio_periph = GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); +inline uint32_t gd32_gpio_to_periph(const uint32_t gpio) { + switch ((GD32_Port_TypeDef) GD32_GPIO_TO_PORT(gpio)) { + case GD32_GPIO_PORTA: + case GD32_GPIO_PORTB: + case GD32_GPIO_PORTC: + case GD32_GPIO_PORTD: + case GD32_GPIO_PORTE: + case GD32_GPIO_PORTF: + case GD32_GPIO_PORTG: + return GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); + break; +#if !(defined (GD32F10X) || defined (GD32F30X)) + case GD32_GPIO_PORTH: + return GPIOH; + break; +# if !defined (GD32H7XX) + case GD32_GPIO_PORTI: + return GPIOI; + break; +# endif +#endif +#if defined (GD32H7XX) + case GD32_GPIO_PORTJ: + return GPIOJ; + break; + case GD32_GPIO_PORTK: + return GPIOK; + break; +#endif + default: + assert(0); + return 0; + break; + } +} + +inline void gd32_gpio_fsel(const uint32_t gpio, const uint32_t fsel) { + const uint32_t gpio_periph = gd32_gpio_to_periph(gpio); const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); - GPIO_BC(gpio_periph) = (uint32_t) pin; + gpio_fsel(gpio_periph, pin, fsel); } -inline static void gd32_gpio_set(const uint32_t gpio) { - const uint32_t gpio_periph = GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); +inline void gd32_gpio_clr(const uint32_t gpio) { + const uint32_t gpio_periph = gd32_gpio_to_periph(gpio); const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); - GPIO_BOP(gpio_periph) = (uint32_t) pin; + GPIO_BC(gpio_periph) = pin; } -inline static void gd32_gpio_write(const uint32_t gpio, const uint32_t level) { +inline void gd32_gpio_set(const uint32_t gpio) { + const uint32_t gpio_periph = gd32_gpio_to_periph(gpio); + const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); + + GPIO_BOP(gpio_periph) = pin; +} + +inline void gd32_gpio_write(const uint32_t gpio, const uint32_t level) { if (level == 0) { gd32_gpio_clr(gpio); } else { @@ -181,10 +211,135 @@ inline static void gd32_gpio_write(const uint32_t gpio, const uint32_t level) { } } -inline static uint32_t gd32_gpio_lev(const uint32_t gpio) { - const uint32_t gpio_periph = GPIOA + (GD32_GPIO_TO_PORT(gpio) * 0x400); +inline uint32_t gd32_gpio_lev(const uint32_t gpio) { + const uint32_t gpio_periph = gd32_gpio_to_periph(gpio); const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); - return (uint32_t) ((uint32_t) 0 != (GPIO_ISTAT(gpio_periph) & pin)); + + return (uint32_t)(0 != (GPIO_ISTAT(gpio_periph) & pin)); } +inline void gd32_gpio_set_pud(const uint32_t gpio, const uint32_t pud) { + const uint32_t gpio_periph = gd32_gpio_to_periph(gpio); + const uint32_t pin = BIT(GD32_GPIO_TO_NUMBER(gpio)); + +#if defined (GD32F10X) || defined (GD32F20X) || defined (GD32F30X) + gpio_init(gpio_periph, pud, GPIO_OSPEED_50MHZ, pin); +#elif defined (GD32F4XX) || defined (GD32H7XX) + if (pud == GPIO_PULL_UP) { + gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, pin); + } else if (pud == GPIO_PULL_DOWN) { + gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, pin); + } else { + gpio_mode_set(gpio_periph, GPIO_MODE_INPUT, GPIO_PUPD_NONE, pin); + } +#endif +} + +#if defined (GD32F4XX) || defined (GD32H7XX) +template +inline void gd32_gpio_mode_set() { + static_assert(pin != 0, "pin cannot be zero"); + static_assert(pin == (1U << __builtin_ctz(pin)), "Only single pin values are allowed"); + + uint32_t ctl = GPIO_CTL(gpio_periph); + uint32_t pupd = GPIO_PUD(gpio_periph); + + constexpr auto i = 31U - __builtin_clz(pin); + + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +template +inline void gd32_gpio_af_set() { + static_assert(pin != 0, "pin cannot be zero"); + static_assert(pin == (1U << __builtin_ctz(pin)), "Only single pin values are allowed"); + + constexpr uint32_t i = 31U - __builtin_clz(pin); + + auto afrl = GPIO_AFSEL0(gpio_periph); + auto afrh = GPIO_AFSEL1(gpio_periph); + + if constexpr(i < 8U) { + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i, alt_func_num); + } else if constexpr(i < 16U) { + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U, alt_func_num); + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} +#else +template +inline void gd32_gpio_init() { + /* GPIO mode configuration */ + auto temp_mode = (mode & 0x0F); + + /* GPIO speed configuration */ + if constexpr ((0x00U) != (mode & (0x10U))) { + /* output mode max speed: 10MHz, 2MHz, 50MHz */ + temp_mode |= speed; + } + + constexpr uint32_t pin_pos = 31U - __builtin_clz(pin); + + if constexpr (pin_pos < 8U) { + uint32_t reg = GPIO_CTL0(gpio_periph); + /* clear the specified pin mode bits */ + reg &= ~GPIO_MODE_MASK(pin_pos); + /* set the specified pin mode bits */ + reg |= GPIO_MODE_SET(pin_pos, temp_mode); + + /* set IPD or IPU */ + if constexpr (GPIO_MODE_IPD == mode) { + /* reset the corresponding OCTL bit */ + GPIO_BC(gpio_periph) = (1U << pin_pos); + } else { + /* set the corresponding OCTL bit */ + if constexpr (GPIO_MODE_IPU == mode) { + GPIO_BOP(gpio_periph) = (1U << pin_pos); + } + } + /* set GPIO_CTL0 register */ + GPIO_CTL0(gpio_periph) = reg; + } else { + /* configure the eight high port pins with GPIO_CTL1 */ + constexpr uint32_t high_pin_pos = pin_pos - 8U; + uint32_t reg = GPIO_CTL1(gpio_periph); + /* clear the specified pin mode bits */ + reg &= ~GPIO_MODE_MASK(high_pin_pos); + /* set the specified pin mode bits */ + reg |= GPIO_MODE_SET(high_pin_pos, temp_mode); + + /* set IPD or IPU */ + if constexpr (GPIO_MODE_IPD == mode) { + /* reset the corresponding OCTL bit */ + GPIO_BC(gpio_periph) = (1U << pin_pos); + } else { + /* set the corresponding OCTL bit */ + if (GPIO_MODE_IPU == mode) { + GPIO_BOP(gpio_periph) = (1U << pin_pos); + } + } + /* set GPIO_CTL1 register */ + GPIO_CTL1(gpio_periph) = reg; + } +} +#endif +#endif + #endif /* GD32_GPIO_H_ */ diff --git a/lib-gd32/include/gd32_ptp.h b/lib-gd32/include/gd32_ptp.h new file mode 100644 index 0000000..c1eb623 --- /dev/null +++ b/lib-gd32/include/gd32_ptp.h @@ -0,0 +1,98 @@ +/** + * @file gd32_ptp.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GD32_PTP_H_ +#define GD32_PTP_H_ + +#include + +#include "gd32.h" + +namespace gd32 { +namespace ptp { +#if !defined(MCU_CLOCK_FREQ) +# error MCU_CLOCK_FREQ is not defined +#endif +#if !defined(PTP_ACCARACY_NS) + static constexpr uint8_t PTP_TICK = 20; +#else + static constexpr uint8_t PTP_TICK = PTP_ACCARACY_NS; +#endif +static constexpr uint8_t ADJ_FREQ_BASE_INCREMENT = static_cast((PTP_TICK * static_cast(1ULL << 31) / 1E9) + 0.5f); +static constexpr uint32_t ADJ_FREQ_BASE_ADDEND = (static_cast(1ULL << 63) / AHB_CLOCK_FREQ) / ADJ_FREQ_BASE_INCREMENT; +static constexpr int32_t ADJ_FREQ_MAX = 5120000; + +struct time_t { + int32_t tv_sec; + int32_t tv_nsec; +}; + +struct ptptime { + uint32_t tv_sec; + uint32_t tv_nsec; +}; +} // namespace ptp + +inline uint32_t ptp_nanosecond_2_subsecond(const uint32_t nanosecond) { + uint64_t val = nanosecond * 0x80000000Ull; + val /= 1000000000U; + return static_cast(val); +} + +inline uint32_t ptp_subsecond_2_nanosecond(const uint32_t subsecond) { + uint64_t val = subsecond * 1000000000Ull; + val >>= 31U; + return (uint32_t) val; +} + +inline void normalize_time(ptp::time_t *r) { + r->tv_sec += r->tv_nsec / 1000000000; + r->tv_nsec -= r->tv_nsec / 1000000000 * 1000000000; + + if (r->tv_sec > 0 && r->tv_nsec < 0) { + r->tv_sec -= 1; + r->tv_nsec += 1000000000; + } else if (r->tv_sec < 0 && r->tv_nsec > 0) { + r->tv_sec += 1; + r->tv_nsec -= 1000000000; + } +} + +inline void sub_time(struct ptp::time_t *r, const struct ptp::time_t *x, const struct ptp::time_t *y) { + r->tv_sec = x->tv_sec - y->tv_sec; + r->tv_nsec = x->tv_nsec - y->tv_nsec; + + normalize_time(r); +} + +} // namespace gd32 + +void gd32_ptp_start(); +void gd32_ptp_get_time(gd32::ptp::ptptime *ptp_time); +void gd32_ptp_set_time(const gd32::ptp::ptptime *ptp_time); +void gd32_ptp_update_time(const gd32::ptp::time_t *ptp_time); +bool gd32_adj_frequency(const int32_t adjust_pbb); + +#endif /* GD32_PTP_H_ */ diff --git a/lib-network/src/networkconst.cpp b/lib-gd32/include/gd32_pwm.h similarity index 73% rename from lib-network/src/networkconst.cpp rename to lib-gd32/include/gd32_pwm.h index b70872e..5e3cf8c 100644 --- a/lib-network/src/networkconst.cpp +++ b/lib-gd32/include/gd32_pwm.h @@ -1,8 +1,8 @@ /** - * @file networkconst.cpp + * @file gd32_pwm.h * */ -/* Copyright (C) 2019-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,10 +23,21 @@ * THE SOFTWARE. */ -#include "networkconst.h" +#ifndef GD32_PWM_H_ +#define GD32_PWM_H_ -const char NetworkConst::MSG_NETWORK_INIT[] = "Network init"; -const char NetworkConst::MSG_NETWORK_STARTED[] = "Network started"; +#include -const char NetworkConst::MSG_MDNS_CONFIG[] = "Configuring MDNS"; -const char NetworkConst::MSG_MDNS_STARTED[] = "MDNS started"; +namespace pwm { +enum class Channel { + PWM_CHANNEL_0, + PWM_CHANNEL_1, + PWM_CHANNEL_2, + PWM_CHANNEL_3 +}; +} // namespace pwm + +void gd32_pwm_begin(); +void gd32_pwm_set_duty_cycle(const pwm::Channel channel, const uint32_t nDutyCycle); + +#endif /* GD32_PWM_H_ */ diff --git a/lib-gd32/include/gd32_spi.h b/lib-gd32/include/gd32_spi.h index 9b1f8ad..10d410f 100644 --- a/lib-gd32/include/gd32_spi.h +++ b/lib-gd32/include/gd32_spi.h @@ -2,7 +2,7 @@ * @file gd32_spi.h * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,10 +62,21 @@ void gd32_spi_writenb(const char *pTxBuffer, uint32_t nDataLength); * DMA support */ +const uint8_t *gd32_spi_dma_tx_prepare(uint32_t& nLength); +void gd32_spi_dma_tx_start(const uint8_t *pTxBuffer, uint32_t nLength); +bool gd32_spi_dma_tx_is_active(); + +/** + * SPI DMA implementation using I2S. + * Limitation SPI is that you cannot set the speed exactly. + * Exact speed is needed for pixels (WS2812B, etc). + */ +namespace i2s { void gd32_spi_dma_begin(); -void gd32_spi_dma_set_speed_hz(uint32_t speed_hz); -const uint8_t *gd32_spi_dma_tx_prepare(uint32_t *data_length); -void gd32_spi_dma_tx_start(const uint8_t *tx_buffer, uint32_t length); +void gd32_spi_dma_set_speed_hz(uint32_t nSpeedHz); +const uint8_t *gd32_spi_dma_tx_prepare(uint32_t *pLength); +void gd32_spi_dma_tx_start(const uint8_t *pTxBuffer, uint32_t nLength); bool gd32_spi_dma_tx_is_active(); +} // namespace i2s #endif /* GD32_SPI_H_ */ diff --git a/lib-gd32/include/gd32_uart.h b/lib-gd32/include/gd32_uart.h index 5f3c759..f562f6c 100644 --- a/lib-gd32/include/gd32_uart.h +++ b/lib-gd32/include/gd32_uart.h @@ -2,7 +2,7 @@ * @file gd32_uart.h * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,13 @@ #ifndef GD32_UART_H_ #define GD32_UART_H_ +#if !defined (GD32H7XX) +# define USART_TDATA USART_DATA +# define USART_RDATA USART_DATA +# define USART_TDATA_TDATA USART_DATA_DATA +# define USART_RDATA_TDATA USART_DATA_DATA +#endif + typedef enum GD32_UART_BITS { GD32_UART_BITS_8 = 8, GD32_UART_BITS_9 = 9 @@ -42,27 +49,75 @@ typedef enum GD32_UART_STOPBITS { GD32_UART_STOP_2BITS = 2 } gd32_uart_stopbits_t; -#include +#include #include "gd32.h" -#ifdef __cplusplus -extern "C" { -#endif - -extern void gd32_uart_begin(const uint32_t usart_periph, uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop_bits); -extern void gd32_uart_set_baudrate(const uint32_t usart_periph, uint32_t baudrate); -extern void gd32_uart_transmit(const uint32_t usart_periph, const uint8_t *data, uint32_t length); -extern void gd32_uart_transmit_string(const uint32_t uart_base, const char *data); +void gd32_uart_begin(const uint32_t usart_periph, uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop_bits); +void gd32_uart_set_baudrate(const uint32_t usart_periph, uint32_t baudrate); +void gd32_uart_transmit(const uint32_t usart_periph, const uint8_t *data, uint32_t length); +void gd32_uart_transmit_string(const uint32_t usart_periph, const char *data); -static inline uint32_t gd32_uart_get_rx_fifo_level(__attribute__((unused)) const uint32_t usart_periph) { +inline uint32_t gd32_uart_get_rx_fifo_level(__attribute__((unused)) const uint32_t usart_periph) { return 1; } -static inline uint8_t gd32_uart_get_rx_data(const uint32_t uart_base) { - return (uint8_t)(GET_BITS(USART_DATA(uart_base), 0U, 8U)); +inline uint8_t gd32_uart_get_rx_data(const uint32_t usart_periph) { + return static_cast(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); +} + +template +bool gd32_usart_flag_get(const uint32_t usart_periph) { + return (0 != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))); +} + +template +void gd32_usart_flag_clear(const uint32_t usart_periph) { +#if defined (GD32F10X) || defined (GD32F30X) || defined (GD32F20X) + USART_REG_VAL(usart_periph, flag) = ~BIT(USART_BIT_POS(flag)); +#elif defined (GD32F4XX) + USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag)); +#elif defined (GD32H7XX) + if constexpr (USART_FLAG_AM1 == flag) { + USART_INTC(usart_periph) |= USART_INTC_AMC1; + } else if constexpr (USART_FLAG_EPERR == flag) { + USART_CHC(usart_periph) &= (uint32_t) (~USART_CHC_EPERR); + } else if constexpr (USART_FLAG_TFE == flag) { + USART_FCS(usart_periph) |= USART_FCS_TFEC; + } else { + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); + } +#else +# error +#endif +} + +template +void gd32_usart_interrupt_enable(const uint32_t usart_periph) { + USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt)); } -#ifdef __cplusplus +template +void gd32_usart_interrupt_disable(const uint32_t usart_periph) { + USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt)); } + +template +void gd32_usart_interrupt_flag_clear(const uint32_t usart_periph) { +#if defined (GD32F10X) || defined (GD32F30X) || defined (GD32F20X) + USART_REG_VAL2(usart_periph, flag) = ~BIT(USART_BIT_POS2(flag)); +#elif defined (GD32F4XX) + USART_REG_VAL2(usart_periph, flag) &= ~BIT(USART_BIT_POS2(flag)); +#elif defined (GD32H7XX) + if constexpr (USART_INT_FLAG_TFE == flag) { + USART_FCS(usart_periph) |= USART_FCS_TFEC; + } else if constexpr (USART_INT_FLAG_RFF == flag) { + USART_FCS(usart_periph) &= (~USART_FCS_RFFIF); + } else { + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag)); + } +#else +# error #endif +} + #endif /* GD32_UART_H_ */ diff --git a/lib-gd32/include/logic_analyzer.h b/lib-gd32/include/logic_analyzer.h index ff116a0..c70ef0b 100644 --- a/lib-gd32/include/logic_analyzer.h +++ b/lib-gd32/include/logic_analyzer.h @@ -2,7 +2,7 @@ * @file logic_analyzer.h * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,96 +26,96 @@ #ifndef LOGIC_ANALYZER_H_ #define LOGIC_ANALYZER_H_ +#include "board/logic_analyzer.h" #include "gd32.h" namespace logic_analyzer { - -static void init() { +inline void init() { #if defined (LOGIC_ANALYZER) # if defined (LOGIC_ANALYZER_CH0_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH0_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH0_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH0_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH0_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH0_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH0_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH0_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH0_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH0_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH0_GPIOx) = LOGIC_ANALYZER_CH0_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH1_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH1_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH1_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH1_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH1_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH1_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH1_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH1_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH1_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH1_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH1_GPIOx) = LOGIC_ANALYZER_CH1_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH2_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH2_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH2_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH2_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH2_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH2_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH2_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH2_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH2_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH2_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH2_GPIOx) = LOGIC_ANALYZER_CH2_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH3_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH3_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH3_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH3_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH3_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH3_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH3_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH3_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH3_GPIOx) = LOGIC_ANALYZER_CH3_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH4_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH4_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH4_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH4_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH4_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH4_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH4_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH4_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH4_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH4_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH4_GPIOx) = LOGIC_ANALYZER_CH4_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH5_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH5_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH5_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH5_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH5_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH5_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH5_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH5_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH5_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH5_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH5_GPIOx) = LOGIC_ANALYZER_CH5_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH6_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH6_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH6_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH6_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH6_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH6_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH6_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH6_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH6_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH6_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH6_GPIOx) = LOGIC_ANALYZER_CH6_GPIO_PINx; # endif # if defined (LOGIC_ANALYZER_CH7_GPIO_PINx) rcu_periph_clock_enable(LOGIC_ANALYZER_CH7_RCU_GPIOx); -# if !defined (GD32F4XX) +# if defined (GPIO_INIT) gpio_init(LOGIC_ANALYZER_CH7_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH7_GPIO_PINx); # else gpio_mode_set(LOGIC_ANALYZER_CH7_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LOGIC_ANALYZER_CH7_GPIO_PINx); - gpio_output_options_set(LOGIC_ANALYZER_CH7_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LOGIC_ANALYZER_CH7_GPIO_PINx); + gpio_output_options_set(LOGIC_ANALYZER_CH7_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LOGIC_ANALYZER_CH7_GPIO_PINx); # endif GPIO_BC(LOGIC_ANALYZER_CH7_GPIOx) = LOGIC_ANALYZER_CH7_GPIO_PINx; # endif @@ -123,103 +123,101 @@ static void init() { #endif } -static void ch0_clear() { -#if defined (LOGIC_ANALYZER_CH0_GPIO_PINx) +inline void ch0_clear() { +#if defined (LOGIC_ANALYZER_CH0_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH0_GPIOx) = LOGIC_ANALYZER_CH0_GPIO_PINx; #endif } -static void ch0_set() { -#if defined (LOGIC_ANALYZER_CH0_GPIO_PINx) +inline void ch0_set() { +#if defined (LOGIC_ANALYZER_CH0_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH0_GPIOx) = LOGIC_ANALYZER_CH0_GPIO_PINx; #endif } -static void ch1_clear() { -#if defined (LOGIC_ANALYZER_CH1_GPIO_PINx) +inline void ch1_clear() { +#if defined (LOGIC_ANALYZER_CH1_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH1_GPIOx) = LOGIC_ANALYZER_CH1_GPIO_PINx; #endif } -static void ch1_set() { -#if defined (LOGIC_ANALYZER_CH1_GPIO_PINx) +inline void ch1_set() { +#if defined (LOGIC_ANALYZER_CH1_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH1_GPIOx) = LOGIC_ANALYZER_CH1_GPIO_PINx; #endif } -static void ch2_clear() { -#if defined (LOGIC_ANALYZER_CH2_GPIO_PINx) +inline void ch2_clear() { +#if defined (LOGIC_ANALYZER_CH2_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH2_GPIOx) = LOGIC_ANALYZER_CH2_GPIO_PINx; #endif } -static void ch2_set() { -#if defined (LOGIC_ANALYZER_CH2_GPIO_PINx) +inline void ch2_set() { +#if defined (LOGIC_ANALYZER_CH2_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH2_GPIOx) = LOGIC_ANALYZER_CH2_GPIO_PINx; #endif } -static void ch3_clear() { -#if defined (LOGIC_ANALYZER_CH3_GPIO_PINx) +inline void ch3_clear() { +#if defined (LOGIC_ANALYZER_CH3_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH3_GPIOx) = LOGIC_ANALYZER_CH3_GPIO_PINx; #endif } -static void ch3_set() { -#if defined (LOGIC_ANALYZER_CH3_GPIO_PINx) +inline void ch3_set() { +#if defined (LOGIC_ANALYZER_CH3_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH3_GPIOx) = LOGIC_ANALYZER_CH3_GPIO_PINx; #endif } -// -static void ch4_clear() { -#if defined (LOGIC_ANALYZER_CH4_GPIO_PINx) +inline void ch4_clear() { +#if defined (LOGIC_ANALYZER_CH4_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH4_GPIOx) = LOGIC_ANALYZER_CH4_GPIO_PINx; #endif } -static void ch4_set() { -#if defined (LOGIC_ANALYZER_CH4_GPIO_PINx) +inline void ch4_set() { +#if defined (LOGIC_ANALYZER_CH4_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH4_GPIOx) = LOGIC_ANALYZER_CH4_GPIO_PINx; #endif } -static void ch5_clear() { -#if defined (LOGIC_ANALYZER_CH5_GPIO_PINx) +inline void ch5_clear() { +#if defined (LOGIC_ANALYZER_CH5_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH5_GPIOx) = LOGIC_ANALYZER_CH5_GPIO_PINx; #endif } -static void ch5_set() { -#if defined (LOGIC_ANALYZER_CH5_GPIO_PINx) +inline void ch5_set() { +#if defined (LOGIC_ANALYZER_CH5_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH5_GPIOx) = LOGIC_ANALYZER_CH5_GPIO_PINx; #endif } -static void ch6_clear() { -#if defined (LOGIC_ANALYZER_CH6_GPIO_PINx) +inline void ch6_clear() { +#if defined (LOGIC_ANALYZER_CH6_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH6_GPIOx) = LOGIC_ANALYZER_CH6_GPIO_PINx; #endif } -static void ch6_set() { -#if defined (LOGIC_ANALYZER_CH6_GPIO_PINx) +inline void ch6_set() { +#if defined (LOGIC_ANALYZER_CH6_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH6_GPIOx) = LOGIC_ANALYZER_CH6_GPIO_PINx; #endif } -static void ch7_clear() { -#if defined (LOGIC_ANALYZER_CH7_GPIO_PINx) +inline void ch7_clear() { +#if defined (LOGIC_ANALYZER_CH7_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BC(LOGIC_ANALYZER_CH7_GPIOx) = LOGIC_ANALYZER_CH7_GPIO_PINx; #endif } -static void ch7_set() { -#if defined (LOGIC_ANALYZER_CH7_GPIO_PINx) +inline void ch7_set() { +#if defined (LOGIC_ANALYZER_CH7_GPIO_PINx) && defined (LOGIC_ANALYZER) GPIO_BOP(LOGIC_ANALYZER_CH7_GPIOx) = LOGIC_ANALYZER_CH7_GPIO_PINx; #endif } - } // namespace logic_analyzer #endif /* LOGIC_ANALYZER_H_ */ diff --git a/lib-gd32/include/mcu/gd32f450_mcu.h b/lib-gd32/include/mcu/gd32f450_mcu.h index ef73a5b..8f09e80 100644 --- a/lib-gd32/include/mcu/gd32f450_mcu.h +++ b/lib-gd32/include/mcu/gd32f450_mcu.h @@ -2,7 +2,7 @@ * @file gd32f450_mcu.h * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,6 +43,7 @@ */ #define MCU_CLOCK_FREQ (uint32_t)(200000000) +#define AHB_CLOCK_FREQ (uint32_t)(200000000) #define APB1_CLOCK_FREQ (uint32_t)(50000000) #define APB2_CLOCK_FREQ (uint32_t)(100000000) #define TIMER_PSC_1MHZ (uint16_t)(199) diff --git a/lib-gd32/include/mcu/gd32f4xx_mcu.h b/lib-gd32/include/mcu/gd32f4xx_mcu.h index d8babb0..aa0893f 100644 --- a/lib-gd32/include/mcu/gd32f4xx_mcu.h +++ b/lib-gd32/include/mcu/gd32f4xx_mcu.h @@ -2,7 +2,7 @@ * @file gd32f4xx_mcu.h * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,11 +26,11 @@ #ifndef MCU_GD32F4XX_MCU_H_ #define MCU_GD32F4XX_MCU_H_ -#if !(defined(MCU_GD32F407_MCU_H_) || defined(MCU_GD32F450_MCU_H_)) +#if !(defined(MCU_GD32F407_MCU_H_) || defined(MCU_GD32F450_MCU_H_) || defined(MCU_GD32F470_MCU_H_)) # error This file should not be included #endif -#include +#include /** * @@ -42,211 +42,252 @@ * U(S)ART */ -#define USART0_RCU_CLK RCU_USART0 +#define USART0_RCU_USART0 RCU_USART0 #if defined (USART0_REMAP) -# define USART0_GPIO_PORT GPIOB -# define USART0_GPIO_CLK RCU_GPIOB -# define USART0_TX_PIN GPIO_PIN_6 -# define USART0_RX_PIN GPIO_PIN_7 +# define USART0_GPIO_AFx GPIO_AF_7 +# define USART0_RCU_GPIOx RCU_GPIOB +# define USART0_GPIOx GPIOB +# define USART0_TX_GPIO_PINx GPIO_PIN_6 +# define USART0_RX_GPIO_PINx GPIO_PIN_7 #else -# define USART0_GPIO_PORT GPIOA -# define USART0_GPIO_CLK RCU_GPIOA -# define USART0_TX_PIN GPIO_PIN_9 -# define USART0_RX_PIN GPIO_PIN_10 +# define USART0_GPIO_AFx GPIO_AF_7 +# define USART0_RCU_GPIOx RCU_GPIOA +# define USART0_GPIOx GPIOA +# define USART0_TX_GPIO_PINx GPIO_PIN_9 +# define USART0_RX_GPIO_PINx GPIO_PIN_10 #endif -#define USART1_RCU_CLK RCU_USART1 +#define USART1_RCU_USART1 RCU_USART1 #if defined (USART1_REMAP) -# define USART1_GPIO_PORT GPIOD -# define USART1_GPIO_CLK RCU_GPIOD -# define USART1_TX_PIN GPIO_PIN_5 -# define USART1_RX_PIN GPIO_PIN_6 +# define USART1_GPIO_AFx GPIO_AF_7 +# define USART1_RCU_GPIOx RCU_GPIOD +# define USART1_GPIOx GPIOD +# define USART1_TX_GPIO_PINx GPIO_PIN_5 +# define USART1_RX_GPIO_PINx GPIO_PIN_6 #else -# define USART1_GPIO_PORT GPIOA -# define USART1_GPIO_CLK RCU_GPIOA -# define USART1_TX_PIN GPIO_PIN_2 -# define USART1_RX_PIN GPIO_PIN_3 +# define USART1_GPIO_AFx GPIO_AF_7 +# define USART1_RCU_GPIOx RCU_GPIOA +# define USART1_GPIOx GPIOA +# define USART1_TX_GPIO_PINx GPIO_PIN_2 +# define USART1_RX_GPIO_PINx GPIO_PIN_3 #endif -#define USART2_RCU_CLK RCU_USART2 +#define USART2_RCU_USART2 RCU_USART2 #if defined (USART2_FULL_REMAP) -# define USART2_GPIO_PORT GPIOD -# define USART2_GPIO_CLK RCU_GPIOD -# define USART2_TX_PIN GPIO_PIN_8 -# define USART2_RX_PIN GPIO_PIN_9 +# define USART2_GPIO_AFx GPIO_AF_7 +# define USART2_RCU_GPIOx RCU_GPIOD +# define USART2_GPIOx GPIOD +# define USART2_TX_GPIO_PINx GPIO_PIN_8 +# define USART2_RX_GPIO_PINx GPIO_PIN_9 #elif defined (USART2_PARTIAL_REMAP) -# define USART2_GPIO_PORT GPIOC -# define USART2_GPIO_CLK RCU_GPIOC -# define USART2_TX_PIN GPIO_PIN_10 -# define USART2_RX_PIN GPIO_PIN_11 +# define USART2_GPIO_AFx GPIO_AF_7 +# define USART2_RCU_GPIOx RCU_GPIOC +# define USART2_GPIOx GPIOC +# define USART2_TX_GPIO_PINx GPIO_PIN_10 +# define USART2_RX_GPIO_PINx GPIO_PIN_11 #else -# define USART2_GPIO_PORT GPIOB -# define USART2_GPIO_CLK RCU_GPIOB -# define USART2_TX_PIN GPIO_PIN_10 -# define USART2_RX_PIN GPIO_PIN_11 +# define USART2_GPIO_AFx GPIO_AF_7 +# define USART2_RCU_GPIOx RCU_GPIOB +# define USART2_GPIOx GPIOB +# define USART2_TX_GPIO_PINx GPIO_PIN_10 +# define USART2_RX_GPIO_PINx GPIO_PIN_11 #endif -#define UART3_RCU_CLK RCU_UART3 +#define UART3_RCU_UART3 RCU_UART3 #if defined (UART3_REMAP) -# define UART3_GPIO_PORT GPIOA -# define UART3_GPIO_CLK RCU_GPIOA -# define UART3_TX_PIN GPIO_PIN_0 -# define UART3_RX_PIN GPIO_PIN_1 +# define UART3_GPIO_AFx GPIO_AF_8 +# define UART3_RCU_GPIOx RCU_GPIOA +# define UART3_GPIOx GPIOA +# define UART3_TX_GPIO_PINx GPIO_PIN_0 +# define UART3_RX_GPIO_PINx GPIO_PIN_1 #else -# define UART3_GPIO_PORT GPIOC -# define UART3_GPIO_CLK RCU_GPIOC -# define UART3_TX_PIN GPIO_PIN_10 -# define UART3_RX_PIN GPIO_PIN_11 +# define UART3_GPIO_AFx GPIO_AF_8 +# define UART3_RCU_GPIOx RCU_GPIOC +# define UART3_GPIOx GPIOC +# define UART3_TX_GPIO_PINx GPIO_PIN_10 +# define UART3_RX_GPIO_PINx GPIO_PIN_11 #endif -#define UART4_RCU_CLK RCU_UART4 -#define UART4_GPIO_TX_PORT GPIOC -#define UART4_GPIO_TX_CLK RCU_GPIOC -#define UART4_GPIO_RX_PORT GPIOD -#define UART4_GPIO_RX_CLK RCU_GPIOD -#define UART4_TX_PIN GPIO_PIN_12 -#define UART4_RX_PIN GPIO_PIN_2 +#define UART4_RCU_UART4 RCU_UART4 +#define UART4_GPIO_AFx GPIO_AF_8 +#define UART4_TX_RCU_GPIOx RCU_GPIOC +#define UART4_TX_GPIOx GPIOC +#define UART4_TX_GPIO_PINx GPIO_PIN_12 +#define UART4_RX_RCU_GPIOx RCU_GPIOD +#define UART4_RX_GPIOx GPIOD +#define UART4_RX_GPIO_PINx GPIO_PIN_2 -#define USART5_RCU_CLK RCU_USART5 +#define USART5_RCU_USART5 RCU_USART5 #if defined (USART5_REMAP) -# define USART5_GPIO_PORT GPIOG -# define USART5_GPIO_CLK RCU_GPIOG -# define USART5_TX_PIN GPIO_PIN_14 -# define USART5_RX_PIN GPIO_PIN_9 +# define USART5_GPIO_AFx GPIO_AF_8 +# define USART5_RCU_GPIOx RCU_GPIOG +# define USART5_GPIOx GPIOG +# define USART5_TX_GPIO_PINx GPIO_PIN_14 +# define USART5_RX_GPIO_PINx GPIO_PIN_9 #else -# define USART5_GPIO_PORT GPIOC -# define USART5_GPIO_CLK RCU_GPIOC -# define USART5_TX_PIN GPIO_PIN_6 -# define USART5_RX_PIN GPIO_PIN_7 +# define USART5_GPIO_AFx GPIO_AF_8 +# define USART5_RCU_GPIOx RCU_GPIOC +# define USART5_GPIOx GPIOC +# define USART5_TX_GPIO_PINx GPIO_PIN_6 +# define USART5_RX_GPIO_PINx GPIO_PIN_7 #endif -#define UART6_RCU_CLK RCU_UART6 +#define UART6_RCU_UART6 RCU_UART6 #if defined (UART6_REMAP) -# define UART6_GPIO_PORT GPIOF -# define UART6_GPIO_CLK RCU_GPIOF -# define UART6_TX_PIN GPIO_PIN_7 -# define UART6_RX_PIN GPIO_PIN_6 +# define UART6_GPIO_AFx GPIO_AF_8 +# define UART6_RCU_GPIOx RCU_GPIOF +# define UART6_GPIOx GPIOF +# define UART6_TX_GPIO_PINx GPIO_PIN_7 +# define UART6_RX_GPIO_PINx GPIO_PIN_6 #else -# define UART6_GPIO_PORT GPIOE -# define UART6_GPIO_CLK RCU_GPIOE -# define UART6_TX_PIN GPIO_PIN_8 -# define UART6_RX_PIN GPIO_PIN_7 +# define UART6_GPIO_AFx GPIO_AF_8 +# define UART6_RCU_GPIOx RCU_GPIOE +# define UART6_GPIOx GPIOE +# define UART6_TX_GPIO_PINx GPIO_PIN_8 +# define UART6_RX_GPIO_PINx GPIO_PIN_7 #endif -#define UART7_RCU_CLK RCU_UART7 -#define UART7_GPIO_PORT GPIOE -#define UART7_GPIO_CLK RCU_GPIOE -#define UART7_TX_PIN GPIO_PIN_1 -#define UART7_RX_PIN GPIO_PIN_0 +#define UART7_RCU_UART7 RCU_UART7 +#define UART7_GPIO_AFx GPIO_AF_8 +#define UART7_RCU_GPIOx RCU_GPIOE +#define UART7_GPIOx GPIOE +#define UART7_TX_GPIO_PINx GPIO_PIN_1 +#define UART7_RX_GPIO_PINx GPIO_PIN_0 /** * I2C */ -#define I2C0_PERIPH I2C0 -#define I2C0_RCU_CLK RCU_I2C0 -#define I2C0_SCL_GPIOx GPIOB -#define I2C0_SCL_RCU_GPIOx RCU_GPIOB -#define I2C0_SDA_GPIOx GPIOB -#define I2C0_SDA_RCU_GPIOx RCU_GPIOB +#define I2C0_PERIPH I2C0 +#define I2C0_RCU_I2C0 RCU_I2C0 #if defined (I2C0_REMAP) -# define I2C0_SCL_GPIO_PINx GPIO_PIN_8 -# define I2C0_SDA_GPIO_PINx GPIO_PIN_9 +# define I2C0_GPIO_AFx GPIO_AF_4 +# define I2C0_SCL_RCU_GPIOx RCU_GPIOB +# define I2C0_SCL_GPIOx GPIOB +# define I2C0_SCL_GPIO_PINx GPIO_PIN_8 +# define I2C0_SDA_RCU_GPIOx RCU_GPIOB +# define I2C0_SDA_GPIOx GPIOB +# define I2C0_SDA_GPIO_PINx GPIO_PIN_9 #else -# define I2C0_SCL_GPIO_PINx GPIO_PIN_6 -# define I2C0_SDA_GPIO_PINx GPIO_PIN_7 +# define I2C0_GPIO_AFx GPIO_AF_4 +# define I2C0_SCL_RCU_GPIOx RCU_GPIOB +# define I2C0_SCL_GPIOx GPIOB +# define I2C0_SCL_GPIO_PINx GPIO_PIN_6 +# define I2C0_SDA_RCU_GPIOx RCU_GPIOB +# define I2C0_SDA_GPIOx GPIOB +# define I2C0_SDA_GPIO_PINx GPIO_PIN_7 #endif -#define I2C1_PERIPH I2C1 -#define I2C1_RCU_CLK RCU_I2C1 -#define I2C1_SCL_GPIOx GPIOB -#define I2C1_SCL_RCU_GPIOx RCU_GPIOB -#define I2C1_SDA_GPIOx GPIOB -#define I2C1_SDA_RCU_GPIOx RCU_GPIOB -#define I2C1_SCL_GPIO_PINx GPIO_PIN_10 -#define I2C1_SDA_GPIO_PINx GPIO_PIN_11 +#define I2C1_PERIPH I2C1 +#define I2C1_RCU_I2C1 RCU_I2C1 +#define I2C1_GPIO_AFx GPIO_AF_4 +#define I2C1_SCL_RCU_GPIOx RCU_GPIOB +#define I2C1_SCL_GPIOx GPIOB +#define I2C1_SCL_GPIO_PINx GPIO_PIN_10 +#define I2C1_SDA_RCU_GPIOx RCU_GPIOB +#define I2C1_SDA_GPIOx GPIOB +#define I2C1_SDA_GPIO_PINx GPIO_PIN_11 //TODO I2C1 REMAP -#define I2C2_PERIPH I2C2 -#define I2C2_RCU_CLK RCU_I2C2 +#define I2C2_PERIPH I2C2 +#define I2C2_RCU_I2C2 RCU_I2C2 #if defined (I2C2_REMAP) -# define I2C2_GPIO_SCL_PORT GPIOH -# define I2C2_GPIO_SCL_CLK RCU_GPIOH -# define I2C2_SCL_PIN GPIO_PIN_7 -# define I2C2_GPIO_SDA_PORT GPIOH -# define I2C2_GPIO_SDA_CLK RCU_GPIOH -# define I2C2_SDA_PIN GPIO_PIN_8 +# define I2C2_GPIO_AFx GPIO_AF_4 +# define I2C2_SCL_RCU_GPIOx RCU_GPIOH +# define I2C2_SCL_GPIOx GPIOH +# define I2C2_SCL_GPIO_PINx GPIO_PIN_7 +# define I2C2_SDA_RCU_GPIOx RCU_GPIOH +# define I2C2_SDA_GPIOx GPIOH +# define I2C2_SDA_GPIO_PINx GPIO_PIN_8 #else -# define I2C2_GPIO_SCL_PORT GPIOA -# define I2C2_GPIO_SCL_CLK RCU_GPIOA -# define I2C2_SCL_PIN GPIO_PIN_8 -# define I2C2_GPIO_SDA_PORT GPIOC -# define I2C2_GPIO_SDA_CLK RCU_GPIOC -# define I2C2_SDA_PIN GPIO_PIN_9 +# define I2C2_GPIO_AFx GPIO_AF_4 +# define I2C2_SCL_RCU_GPIOx RCU_GPIOA +# define I2C2_SCL_GPIOx GPIOA +# define I2C2_SCL_GPIO_PINx GPIO_PIN_8 +# define I2C2_SDA_RCU_GPIOx RCU_GPIOC +# define I2C2_SDA_GPIOx GPIOC +# define I2C2_SDA_GPIO_PINx GPIO_PIN_9 #endif /** * SPI */ -#define SPI0_PERiPH SPI0 -#define SPI0_RCU_CLK RCU_SPI0 +#define SPI0_PERIPH SPI0 +#define SPI0_RCU_SPI0 RCU_SPI0 #if defined (SPI0_REMAP) -# define SPI0_REMAP_GPIO GPIO_SPI0_REMAP -# define SPI0_NSS_GPIOx GPIOA -# define SPI0_NSS_RCU_GPIOx RCU_GPIOA -# define SPI0_NSS_GPIO_PINx GPIO_PIN_15 +# define SPI0_GPIO_AFx GPIO_AF_5 # define SPI0_GPIOx GPIOB # define SPI0_RCU_GPIOx RCU_GPIOB # define SPI0_SCK_GPIO_PINx GPIO_PIN_3 # define SPI0_MISO_GPIO_PINx GPIO_PIN_4 # define SPI0_MOSI_GPIO_PINx GPIO_PIN_5 -#else -# define SPI0_NSS_GPIOx GPIOA # define SPI0_NSS_RCU_GPIOx RCU_GPIOA -# define SPI0_NSS_GPIO_PINx GPIO_PIN_4 +# define SPI0_NSS_GPIOx GPIOA +# define SPI0_NSS_GPIO_PINx GPIO_PIN_15 +#else +# define SPI0_GPIO_AFx GPIO_AF_5 # define SPI0_GPIOx GPIOA # define SPI0_RCU_GPIOx RCU_GPIOA # define SPI0_SCK_GPIO_PINx GPIO_PIN_5 # define SPI0_MISO_GPIO_PINx GPIO_PIN_6 # define SPI0_MOSI_GPIO_PINx GPIO_PIN_7 +# define SPI0_NSS_RCU_GPIOx RCU_GPIOA +# define SPI0_NSS_GPIOx GPIOA +# define SPI0_NSS_GPIO_PINx GPIO_PIN_4 #endif #define SPI1_PERIPH SPI1 -#define SPI1_RCU_CLK RCU_SPI1 -#define SPI1_NSS_GPIOx GPIOB -#define SPI1_NSS_RCU_GPIOx RCU_GPIOB -#define SPI1_NSS_GPIO_PINx GPIO_PIN_12 -#define SPI1_GPIOx GPIOB +#define SPI1_GPIO_AFx GPIO_AF_5 +#define SPI1_RCU_SPI1 RCU_SPI1 #define SPI1_RCU_GPIOx RCU_GPIOB +#define SPI1_GPIOx GPIOB #define SPI1_SCK_GPIO_PINx GPIO_PIN_13 #define SPI1_MISO_GPIO_PINx GPIO_PIN_14 #define SPI1_MOSI_GPIO_PINx GPIO_PIN_15 +#define SPI1_NSS_RCU_GPIOx RCU_GPIOB +#define SPI1_NSS_GPIOx GPIOB +#define SPI1_NSS_GPIO_PINx GPIO_PIN_12 //TODO SPI1 REMAP #define SPI2_PERIPH SPI2 -#define SPI2_RCU_CLK RCU_SPI2 +#define SPI2_RCU_SPI2 RCU_SPI2 #if defined (SPI2_REMAP) -# define SPI2_REMAP_GPIO GPIO_SPI2_REMAP -# define SPI2_NSS_GPIOx GPIOA -# define SPI2_NSS_RCU_GPIOx RCU_GPIOA -# define SPI2_NSS_GPIO_PINx GPIO_PIN_4 -# define SPI2_GPIOx GPIOC +# define SPI2_GPIO_AFx GPIO_AF_6 # define SPI2_RCU_GPIOx RCU_GPIOC +# define SPI2_GPIOx GPIOC # define SPI2_SCK_GPIO_PINx GPIO_PIN_10 # define SPI2_MISO_GPIO_PINx GPIO_PIN_11 # define SPI2_MOSI_GPIO_PINx GPIO_PIN_12 -#else -# define SPI2_NSS_GPIOx GPIOA # define SPI2_NSS_RCU_GPIOx RCU_GPIOA -# define SPI2_NSS_GPIO_PINx GPIO_PIN_15 -# define SPI2_GPIOx GPIOB +# define SPI2_NSS_GPIOx GPIOA +# define SPI2_NSS_GPIO_PINx GPIO_PIN_4 +#else +# define SPI2_GPIO_AFx GPIO_AF_6 # define SPI2_RCU_GPIOx RCU_GPIOB +# define SPI2_GPIOx GPIOB # define SPI2_SCK_GPIO_PINx GPIO_PIN_3 # define SPI2_MISO_GPIO_PINx GPIO_PIN_4 # define SPI2_MOSI_GPIO_PINx GPIO_PIN_5 +# define SPI2_NSS_RCU_GPIOx RCU_GPIOA +# define SPI2_NSS_GPIOx GPIOA +# define SPI2_NSS_GPIO_PINx GPIO_PIN_15 #endif +#define SPI5_PERIPH SPI5 +#define SPI5_RCU_SPI5 RCU_SPI5 +#define SPI5_GPIO_AFx GPIO_AF_5 +#define SPI5_RCU_GPIOx RCU_GPIOG +#define SPI5_GPIOx GPIOG +#define SPI5_SCK_GPIO_PINx GPIO_PIN_13 +#define SPI5_MISO_GPIO_PINx GPIO_PIN_12 +#define SPI5_MOSI_GPIO_PINx GPIO_PIN_14 +#define SPI5_IO2_GPIO_PINx GPIO_PIN_10 +#define SPI5_IO3_GPIO_PINx GPIO_PIN_11 +#define SPI5_NSS_RCU_GPIOx RCU_GPIOG +#define SPI5_NSS_GPIOx GPIOG +#define SPI5_NSS_GPIO_PINx GPIO_PIN_9 + /** * TIMER GPIO */ @@ -256,21 +297,86 @@ #define TIMER2CH0_GPIOx GPIOA #define TIMER2CH0_GPIO_PINx GPIO_PIN_6 +#if defined(TIMER2_FULL_REMAP) +# define TIMER2_GPIO_AFx GPIO_AF_2 +# define TIMER2_CH0_RCU_GPIOx RCU_GPIOC +# define TIMER2_CH0_GPIOx GPIOC +# define TIMER2_CH0_GPIO_PINx GPIO_PIN_6 + +# define TIMER2_CH1_RCU_GPIOx RCU_GPIOC +# define TIMER2_CH1_GPIOx GPIOC +# define TIMER2_CH1_GPIO_PINx GPIO_PIN_7 + +# define TIMER2_CH2_RCU_GPIOx RCU_GPIOC +# define TIMER2_CH2_GPIOx GPIOC +# define TIMER2_CH2_GPIO_PINx GPIO_PIN_8 + +# define TIMER2_CH3_RCU_GPIOx RCU_GPIOC +# define TIMER2_CH3_GPIOx GPIOC +# define TIMER2_CH3_GPIO_PINx GPIO_PIN_9 +#elif defined(TIMER2_PARTIAL_REMAP) +# define TIMER2_GPIO_AFx GPIO_AF_2 +# define TIMER2_CH0_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH0_GPIOx GPIOB +# define TIMER2_CH0_GPIO_PINx GPIO_PIN_4 + +# define TIMER2_CH1_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH1_GPIOx GPIOB +# define TIMER2_CH1_GPIO_PINx GPIO_PIN_5 + +# define TIMER2_CH2_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH2_GPIOx GPIOB +# define TIMER2_CH2_GPIO_PINx GPIO_PIN_0 + +# define TIMER2_CH3_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH3_GPIOx GPIOB +# define TIMER2_CH3_GPIO_PINx GPIO_PIN_1 +#else +# define TIMER2_GPIO_AFx GPIO_AF_2 +# define TIMER2_CH0_RCU_GPIOx RCU_GPIOA +# define TIMER2_CH0_GPIOx GPIOA +# define TIMER2_CH0_GPIO_PINx GPIO_PIN_6 + +# define TIMER2_CH1_RCU_GPIOx RCU_GPIOA +# define TIMER2_CH1_GPIOx GPIOA +# define TIMER2_CH1_GPIO_PINx GPIO_PIN_7 + +# define TIMER2_CH2_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH2_GPIOx GPIOB +# define TIMER2_CH2_GPIO_PINx GPIO_PIN_0 + +# define TIMER2_CH3_RCU_GPIOx RCU_GPIOB +# define TIMER2_CH3_GPIOx GPIOB +# define TIMER2_CH3_GPIO_PINx GPIO_PIN_1 +#endif + /** * DMA */ -#define SPI0_DMAx DMA1 -#define SPI0_TX_DMA_CHx DMA_CH2 +#define SPI0_DMAx DMA1 +#define SPI0_TX_DMA_CHx DMA_CH2 #define SPI0_TX_DMA_SUBPERIx DMA_SUBPERI3 -#define SPI1_DMAx DMA0 -#define SPI1_TX_DMA_CHx DMA_CH4 +#define SPI1_DMAx DMA0 +#define SPI1_TX_DMA_CHx DMA_CH4 #define SPI1_TX_DMA_SUBPERIx DMA_SUBPERI0 -#define SPI2_DMAx DMA0 -#define SPI2_TX_DMA_CHx DMA_CH5 -#define SPI2_TX_DMA_SUBPERIx DMA_SUBPERI0 +#define SPI2_DMAx DMA0 +#define SPI2_TX_DMA_CHx DMA_CH5 +#define SPI2_TX_DMA_SUBPERIx DMA_SUBPERI0 + +#define SPI3_DMAx DMA1 +#define SPI3_TX_DMA_CHx DMA_CH1 +#define SPI3_TX_DMA_SUBPERIx DMA_SUBPER4 + +#define SPI4_DMAx DMA1 +#define SPI4_TX_DMA_CHx DMA_CH4 +#define SPI4_TX_DMA_SUBPERIx DMA_SUBPERI2 + +#define SPI5_DMAx DMA1 +#define SPI5_TX_DMA_CHx DMA_CH5 +#define SPI5_TX_DMA_SUBPERIx DMA_SUBPERI1 #define TIMER2_RCU_DMAx RCU_DMA0 #define TIMER2_DMAx DMA0 @@ -292,52 +398,52 @@ #define TIMER7_CH2_DMA_CHx DMA_CH4 #define TIMER7_CH2_DMA_SUBPERIx DMA_SUBPERI7 -#define USART0_DMA DMA1 -#define USART0_TX_DMA_CH DMA_CH7 +#define USART0_DMAx DMA1 +#define USART0_TX_DMA_CHx DMA_CH7 #define USART0_TX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART0_RX_DMA_CH DMA_CH5 +#define USART0_RX_DMA_CHx DMA_CH5 #define USART0_RX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART1_DMA DMA0 -#define USART1_TX_DMA_CH DMA_CH6 +#define USART1_DMAx DMA0 +#define USART1_TX_DMA_CHx DMA_CH6 #define USART1_TX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART1_RX_DMA_CH DMA_CH5 +#define USART1_RX_DMA_CHx DMA_CH5 #define USART1_RX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART2_DMA DMA0 -#define USART2_TX_DMA_CH DMA_CH3 +#define USART2_DMAx DMA0 +#define USART2_TX_DMA_CHx DMA_CH3 #define USART2_TX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART2_RX_DMA_CH DMA_CH1 +#define USART2_RX_DMA_CHx DMA_CH1 #define USART2_RX_DMA_SUBPERIx DMA_SUBPERI4 -#define UART3_DMA DMA0 -#define UART3_TX_DMA_CH DMA_CH4 +#define UART3_DMAx DMA0 +#define UART3_TX_DMA_CHx DMA_CH4 #define UART3_TX_DMA_SUBPERIx DMA_SUBPERI4 -#define UART3_RX_DMA_CH DMA_CH2 +#define UART3_RX_DMA_CHx DMA_CH2 #define UART3_RX_DMA_SUBPERIx DMA_SUBPERI4 -#define UART4_DMA DMA0 -#define UART4_TX_DMA_CH DMA_CH7 +#define UART4_DMAx DMA0 +#define UART4_TX_DMA_CHx DMA_CH7 #define UART4_TX_DMA_SUBPERIx DMA_SUBPERI4 -#define UART4_RX_DMA_CH DMA_CH0 +#define UART4_RX_DMA_CHx DMA_CH0 #define UART4_RX_DMA_SUBPERIx DMA_SUBPERI4 -#define USART5_DMA DMA1 -#define USART5_TX_DMA_CH DMA_CH6 +#define USART5_DMAx DMA1 +#define USART5_TX_DMA_CHx DMA_CH6 #define USART5_TX_DMA_SUBPERIx DMA_SUBPERI5 -#define USART5_RX_DMA_CH DMA_CH1 +#define USART5_RX_DMA_CHx DMA_CH1 #define USART5_RX_DMA_SUBPERIx DMA_SUBPERI5 -#define UART6_DMA DMA0 -#define UART6_TX_DMA_CH DMA_CH1 +#define UART6_DMAx DMA0 +#define UART6_TX_DMA_CHx DMA_CH1 #define UART6_TX_DMA_SUBPERIx DMA_SUBPERI5 -#define UART6_RX_DMA_CH DMA_CH3 +#define UART6_RX_DMA_CHx DMA_CH3 #define UART6_RX_DMA_SUBPERIx DMA_SUBPERI5 -#define UART7_DMA DMA0 -#define UART7_TX_DMA_CH DMA_CH0 +#define UART7_DMAx DMA0 +#define UART7_TX_DMA_CHx DMA_CH0 #define UART7_TX_DMA_SUBPERIx DMA_SUBPERI5 -#define UART7_RX_DMA_CH DMA_CH6 +#define UART7_RX_DMA_CHx DMA_CH6 #define UART7_RX_DMA_SUBPERIx DMA_SUBPERI5 #endif /* MCU_GD32F4XX_MCU_H_ */ diff --git a/lib-gd32/src/bkp.cpp b/lib-gd32/src/bkp.cpp index 74349c5..bd4d57d 100644 --- a/lib-gd32/src/bkp.cpp +++ b/lib-gd32/src/bkp.cpp @@ -2,7 +2,7 @@ * @file bkp.cpp * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,18 +23,39 @@ * THE SOFTWARE. */ +#include + #include "gd32.h" -#if defined (GD32F4XX) +#if defined (GD32F4XX) || defined (GD32H7XX) void bkp_data_write(bkp_data_register_enum register_number, uint16_t data) { - if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_1)) { - REG16((BKPSRAM_BASE) + 16 + (register_number) * 2) = data; + switch (register_number) { + case BKP_DATA_0: + RTC_BKP0 = (uint32_t) data; + break; + case BKP_DATA_1: + RTC_BKP1 = (uint32_t) data; + break; + default: + assert(0); + break; } } + uint16_t bkp_data_read(bkp_data_register_enum register_number) { - if ((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_1)) { - return REG16((BKPSRAM_BASE) + 16 + (register_number) * 2); + switch (register_number) { + case BKP_DATA_0: + return RTC_BKP0; + break; + case BKP_DATA_1: + return RTC_BKP1; + break; + default: + assert(0); + break; } + + assert(0); return 0; } #endif diff --git a/lib-gd32/src/gd32_adc.cpp b/lib-gd32/src/f/gd32_adc.cpp similarity index 96% rename from lib-gd32/src/gd32_adc.cpp rename to lib-gd32/src/f/gd32_adc.cpp index 4347921..294b295 100644 --- a/lib-gd32/src/gd32_adc.cpp +++ b/lib-gd32/src/f/gd32_adc.cpp @@ -27,7 +27,7 @@ #include "gd32.h" -void gd32_adc_init(void) { +void gd32_adc_init() { rcu_periph_clock_enable(RCU_ADC0); #if !defined (GD32F4XX) rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV12); @@ -86,21 +86,20 @@ void gd32_adc_init(void) { adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL); } -float gd32_adc_gettemp(void) { - /* value convert */ +float gd32_adc_gettemp() { const float temperature = (1.43f - ADC_IDATA0(ADC0) * 3.3f / 4096) * 1000 / 4.3f + 25; adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL); return temperature; } -float gd32_adc_getvref(void) { +float gd32_adc_getvref() { const float vref_value = (ADC_IDATA1(ADC0) * 3.3f / 4096); adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL); return vref_value; } #if defined (GD32F4XX) -float gd32_adc_getvbat(void) { +float gd32_adc_getvbat() { const float vref_value = (ADC_IDATA2(ADC0) * 3.3f / 4096) * 4; adc_software_trigger_enable(ADC0, ADC_INSERTED_CHANNEL); return vref_value; diff --git a/lib-gd32/src/f/gd32_dma_memcpy32.cpp b/lib-gd32/src/f/gd32_dma_memcpy32.cpp new file mode 100644 index 0000000..55625b3 --- /dev/null +++ b/lib-gd32/src/f/gd32_dma_memcpy32.cpp @@ -0,0 +1,55 @@ +/* + * gd32_dma_memcpy32.cpp + */ + +#include +#include + +#include "gd32.h" + +namespace dma { +void memcpy32_init() { +#if !defined (GD32F4XX) + rcu_periph_clock_enable(RCU_DMA0); + dma_deinit(DMA0, DMA_CH3); + + dma_parameter_struct dma_init_struct; + dma_struct_para_init(&dma_init_struct); + + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; +// dma_init_struct.memory_addr = destination; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_32BIT; + dma_init_struct.number = 0; // BUFFER_SIZE; +// dma_init_struct.periph_addr = source + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_ENABLE; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_32BIT; + dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; + + dma_init(DMA0, DMA_CH3, &dma_init_struct); + dma_circulation_disable(DMA0, DMA_CH3); + dma_memory_to_memory_enable(DMA0, DMA_CH3); +#else + rcu_periph_clock_enable(RCU_DMA1); + dma_deinit(DMA1, DMA_CH0); + + dma_multi_data_parameter_struct dma_init_parameter; + +// dma_init_parameter.periph_addr = source; + dma_init_parameter.periph_width = DMA_PERIPH_WIDTH_32BIT; + dma_init_parameter.periph_inc = DMA_PERIPH_INCREASE_ENABLE; +// dma_init_parameter.memory0_addr = destination; + dma_init_parameter.memory_width = DMA_MEMORY_WIDTH_32BIT; + dma_init_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init_parameter.memory_burst_width = DMA_MEMORY_BURST_4_BEAT; + dma_init_parameter.periph_burst_width = DMA_PERIPH_BURST_4_BEAT; + dma_init_parameter.critical_value = DMA_FIFO_4_WORD; + dma_init_parameter.circular_mode = DMA_CIRCULAR_MODE_DISABLE; + dma_init_parameter.direction = DMA_MEMORY_TO_MEMORY; + dma_init_parameter.number = 0; // BUFFER_SIZE; + dma_init_parameter.priority = DMA_PRIORITY_ULTRA_HIGH; + + dma_multi_data_mode_init(DMA1, DMA_CH0, &dma_init_parameter); +#endif +} +} // namespace dma diff --git a/lib-gd32/src/gd32_i2c.cpp b/lib-gd32/src/f/gd32_i2c.cpp similarity index 67% rename from lib-gd32/src/gd32_i2c.cpp rename to lib-gd32/src/f/gd32_i2c.cpp index 2a23399..880f114 100644 --- a/lib-gd32/src/gd32_i2c.cpp +++ b/lib-gd32/src/f/gd32_i2c.cpp @@ -2,7 +2,7 @@ * @file gd32_i2c.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,7 @@ */ #include +#include #include "gd32_i2c.h" #include "gd32.h" @@ -32,21 +33,18 @@ static constexpr int32_t TIMEOUT = 0xfff; static uint8_t s_nAddress; -static int32_t _sendstart(void) { +static int32_t send_start() { auto nTimeout = TIMEOUT; - /* wait until I2C bus is idle */ while (i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY)) { if (--nTimeout <= 0) { return -GD32_I2C_NOK_TOUT; } } - nTimeout = TIMEOUT; - - /* send a start condition to I2C bus */ i2c_start_on_bus(I2C_PERIPH); + nTimeout = TIMEOUT; /* wait until SBSEND bit is set */ while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND)) { if (--nTimeout <= 0) { @@ -57,25 +55,22 @@ static int32_t _sendstart(void) { return GD32_I2C_OK; } -static int32_t _sendslaveaddr(void) { - auto nTimeout = TIMEOUT; - - /* send slave address to I2C bus */ +static int32_t send_slaveaddr() { i2c_master_addressing(I2C_PERIPH, s_nAddress, I2C_TRANSMITTER); - /* wait until ADDSEND bit is set */ + auto nTimeout = TIMEOUT; + while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND)) { if (--nTimeout <= 0) { return -GD32_I2C_NOK_TOUT; } } - /* clear the ADDSEND bit */ + i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND); nTimeout = TIMEOUT; - /* wait until the transmit data buffer is empty */ while (SET != i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE)) { if (--nTimeout <= 0) { return -GD32_I2C_NOK_TOUT; @@ -85,10 +80,9 @@ static int32_t _sendslaveaddr(void) { return GD32_I2C_OK; } -static int32_t _stop(void) { +static int32_t send_stop() { auto nTimeout = TIMEOUT; - /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C_PERIPH); /* wait until the stop condition is finished */ @@ -101,18 +95,12 @@ static int32_t _stop(void) { return GD32_I2C_OK; } -static int32_t _senddata(uint8_t *pData, uint32_t nCount) { - int32_t nTimeout; - +static int32_t send_data(const uint8_t *pData, const uint32_t nCount) { for (uint32_t i = 0; i < nCount; i++) { i2c_data_transmit(I2C_PERIPH, *pData); - - /* point to the next byte to be written */ pData++; + auto nTimeout = TIMEOUT; - nTimeout = TIMEOUT; - - /* wait until BTC bit is set */ while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_BTC)) { if (--nTimeout <= 0) { return -GD32_I2C_NOK_TOUT; @@ -123,60 +111,72 @@ static int32_t _senddata(uint8_t *pData, uint32_t nCount) { return GD32_I2C_OK; } -static int _write(char *pBuffer, int nLength) { - if (_sendstart() != GD32_I2C_OK) { - _stop(); +static int32_t write(const char *pBuffer, const int nLength) { + if (send_start() != GD32_I2C_OK) { + send_stop(); return -1; } - if (_sendslaveaddr() != GD32_I2C_OK) { - _stop(); + if (send_slaveaddr() != GD32_I2C_OK) { + send_stop(); return -1; } - if (_senddata((uint8_t*) pBuffer, (uint32_t) nLength) != GD32_I2C_OK) { - _stop(); + if (send_data((uint8_t*) pBuffer, (uint32_t) nLength) != GD32_I2C_OK) { + send_stop(); return -1; } - _stop(); + send_stop(); return 0; } -/* - * Public API's - */ - -void gd32_i2c_begin(void) { - rcu_periph_clock_enable(I2C_RCU_CLK); - rcu_periph_clock_enable(I2C_GPIO_SCL_CLK); - rcu_periph_clock_enable(I2C_GPIO_SDA_CLK); +static void rcu_config() { + rcu_periph_clock_enable(I2C_RCU_I2Cx); + rcu_periph_clock_enable(I2C_SCL_RCU_GPIOx); + rcu_periph_clock_enable(I2C_SDA_RCU_GPIOx); +} -#if !defined (GD32F4XX) - gpio_init(I2C_GPIO_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); - gpio_init(I2C_GPIO_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); +static void gpio_config() { +#if defined (GPIO_INIT) + gpio_init(I2C_SCL_GPIOx, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PINx); + gpio_init(I2C_SDA_GPIOx, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PINx); # if defined (I2C_REMAP) if (I2C_REMAP == GPIO_I2C0_REMAP) { gpio_pin_remap_config(GPIO_I2C0_REMAP, ENABLE); + } else { + assert(0); } # endif #else - gpio_af_set(I2C_GPIO_SCL_PORT, GPIO_AF_4, I2C_SCL_PIN); - gpio_af_set(I2C_GPIO_SCL_PORT, GPIO_AF_4, I2C_SDA_PIN); + gpio_af_set(I2C_SCL_GPIOx, I2C_GPIO_AFx, I2C_SCL_GPIO_PINx); + gpio_mode_set(I2C_SCL_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_GPIO_PINx); + gpio_output_options_set(I2C_SCL_GPIOx, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_GPIO_PINx); - gpio_mode_set(I2C_GPIO_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN); - gpio_output_options_set(I2C_GPIO_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); - gpio_mode_set(I2C_GPIO_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN); - gpio_output_options_set(I2C_GPIO_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); + gpio_af_set(I2C_SDA_GPIOx, I2C_GPIO_AFx, I2C_SDA_GPIO_PINx); + gpio_mode_set(I2C_SDA_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_GPIO_PINx); + gpio_output_options_set(I2C_SDA_GPIOx, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_GPIO_PINx); #endif +} +static void i2c_config() { i2c_clock_config(I2C_PERIPH, GD32_I2C_FULL_SPEED, I2C_DTCY_2); i2c_enable(I2C_PERIPH); i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE); } +/* + * Public API's + */ + +void gd32_i2c_begin() { + rcu_config(); + gpio_config(); + i2c_config(); +} + void gd32_i2c_set_baudrate(uint32_t nBaudrate) { i2c_clock_config(I2C_PERIPH, nBaudrate, I2C_DTCY_2); } @@ -186,18 +186,16 @@ void gd32_i2c_set_address(uint8_t nAddress) { } uint8_t gd32_i2c_write(const char *pBuffer, uint32_t nLength) { - const auto ret = _write((char *)pBuffer, (int) nLength); - + const auto ret = write((char *)pBuffer, (int) nLength); return (uint8_t)-ret; } uint8_t gd32_i2c_read(char *pBuffer, uint32_t nLength) { auto nTimeout = TIMEOUT; - /* wait until I2C bus is idle */ while (i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY)) { if (--nTimeout <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } @@ -206,79 +204,67 @@ uint8_t gd32_i2c_read(char *pBuffer, uint32_t nLength) { i2c_ackpos_config(I2C_PERIPH, I2C_ACKPOS_NEXT); } - /* send a start condition to I2C bus */ i2c_start_on_bus(I2C_PERIPH); nTimeout = TIMEOUT; - /* wait until SBSEND bit is set */ while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND)) { if (--nTimeout <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } - /* send slave address to I2C bus */ i2c_master_addressing(I2C_PERIPH, s_nAddress, I2C_RECEIVER); if (nLength < 3) { - /* disable acknowledge */ i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE); } nTimeout = TIMEOUT; - /* wait until ADDSEND bit is set */ while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND)) { if (--nTimeout <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } - /* clear the ADDSEND bit */ i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND); if (1 == nLength) { - /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C_PERIPH); } auto nTimeoutLoop = TIMEOUT; - /* while there is data to be read */ while (nLength) { if (3 == nLength) { nTimeout = TIMEOUT; - /* wait until BTC bit is set */ + while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_BTC)) { if (--nTimeout <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } - /* disable acknowledge */ i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE); } if (2 == nLength) { nTimeout = TIMEOUT; - /* wait until BTC bit is set */ while (!i2c_flag_get(I2C_PERIPH, I2C_FLAG_BTC)) { if (--nTimeout <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } - /* send a stop condition to I2C bus */ i2c_stop_on_bus(I2C_PERIPH); } - /* wait until the RBNE bit is set and clear it */ if (i2c_flag_get(I2C_PERIPH, I2C_FLAG_RBNE)) { *pBuffer = i2c_data_receive(I2C_PERIPH); pBuffer++; @@ -287,23 +273,20 @@ uint8_t gd32_i2c_read(char *pBuffer, uint32_t nLength) { } if (--nTimeoutLoop <= 0) { - _stop(); + send_stop(); return GD32_I2C_NOK_TOUT; } } nTimeout = TIMEOUT; - /* wait until the stop condition is finished */ while (I2C_CTL0(I2C_PERIPH) & 0x0200) { if (--nTimeout <= 0) { return GD32_I2C_NOK_TOUT; } } - /* enable acknowledge */ i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE); - i2c_ackpos_config(I2C_PERIPH, I2C_ACKPOS_CURRENT); return GD32_I2C_OK; diff --git a/lib-gd32/src/gd32_spi.cpp b/lib-gd32/src/f/gd32_spi.cpp similarity index 70% rename from lib-gd32/src/gd32_spi.cpp rename to lib-gd32/src/f/gd32_spi.cpp index 74a9828..5e16577 100644 --- a/lib-gd32/src/gd32_spi.cpp +++ b/lib-gd32/src/f/gd32_spi.cpp @@ -2,7 +2,7 @@ * @file gd32_spi.cpp * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,19 +32,19 @@ static uint8_t s_nChipSelect = GD32_SPI_CS0; -static inline void _cs_high() { +static void cs_high() { if (s_nChipSelect == GD32_SPI_CS0) { - GPIO_BOP(SPI_NSS_GPIOx) = static_cast(SPI_NSS_GPIO_PINx); + GPIO_BOP(SPI_NSS_GPIOx) = SPI_NSS_GPIO_PINx; } } -static inline void _cs_low() { +static void cs_low() { if (s_nChipSelect == GD32_SPI_CS0) { - GPIO_BC(SPI_NSS_GPIOx) = static_cast(SPI_NSS_GPIO_PINx); + GPIO_BC(SPI_NSS_GPIOx) = SPI_NSS_GPIO_PINx; } } -static uint8_t _send_byte(uint8_t byte) { +static uint8_t send_byte(uint8_t byte) { while (RESET == (SPI_STAT(SPI_PERIPH) & SPI_FLAG_TBE)) ; @@ -56,37 +56,44 @@ static uint8_t _send_byte(uint8_t byte) { return static_cast(static_cast(SPI_DATA(SPI_PERIPH))); } -void gd32_spi_begin() { +static void rcu_config() { + rcu_periph_clock_enable(SPI_RCU_SPIx); rcu_periph_clock_enable(SPI_RCU_GPIOx); - rcu_periph_clock_enable(SPI_RCU_CLK); + rcu_periph_clock_enable(SPI_NSS_RCU_GPIOx); -#if !defined (GD32F4XX) +#if defined (GPIO_INIT) rcu_periph_clock_enable(RCU_AF); +#endif +} - gpio_init(SPI_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - -# if defined (SPI_REMAP) - gpio_pin_remap_config(SPI_REMAP, ENABLE); +static void gpio_config() { +#if defined (GPIO_INIT) +# if defined (SPI_REMAP_GPIO) + gpio_pin_remap_config(SPI_REMAP_GPIO, ENABLE); + if (SPI_PERIPH == SPI0) { + gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); + } # else if (SPI_PERIPH == SPI2) { gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); } # endif + gpio_init(SPI_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPI_SCK_GPIO_PINx | SPI_MOSI_GPIO_PINx); + gpio_init(SPI_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SPI_MISO_GPIO_PINx); + gpio_init(SPI_NSS_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPI_NSS_GPIO_PINx); #else - if (SPI_PERIPH == SPI2) { - gpio_af_set(SPI_GPIOx, GPIO_AF_6, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - } else { - gpio_af_set(SPI_GPIOx, GPIO_AF_5, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - } + gpio_af_set(SPI_GPIOx, SPI_GPIO_AFx, SPI_SCK_GPIO_PINx | SPI_MISO_GPIO_PINx | SPI_MOSI_GPIO_PINx); + gpio_mode_set(SPI_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, SPI_SCK_GPIO_PINx | SPI_MISO_GPIO_PINx | SPI_MOSI_GPIO_PINx); + gpio_output_options_set(SPI_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI_SCK_GPIO_PINx | SPI_MOSI_GPIO_PINx); - gpio_mode_set(SPI_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - gpio_output_options_set(SPI_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); + gpio_mode_set(SPI_NSS_GPIOx, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, SPI_NSS_GPIO_PINx); + gpio_output_options_set(SPI_NSS_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, SPI_NSS_GPIO_PINx); #endif - gpio_fsel(SPI_NSS_GPIOx, SPI_NSS_GPIO_PINx, GPIO_FSEL_OUTPUT); - - _cs_high(); + cs_high(); +} +static void spi_config() { spi_disable(SPI_PERIPH); spi_i2s_deinit(SPI_PERIPH); @@ -103,15 +110,23 @@ void gd32_spi_begin() { spi_enable(SPI_PERIPH); } +/* + * Public API's + */ + +void gd32_spi_begin() { + rcu_config(); + gpio_config(); + spi_config(); +} + void gd32_spi_end() { - spi_i2s_deinit(SPI_PERIPH); -#if !defined (GD32F4XX) - gpio_init(SPI_GPIOx, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); + spi_disable(SPI_PERIPH); +#if defined (GPIO_INIT) + gpio_init(SPI_GPIOx, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, SPI_SCK_GPIO_PINx | SPI_MISO_GPIO_PINx | SPI_MOSI_GPIO_PINx); gpio_init(SPI_NSS_GPIOx, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, SPI_NSS_GPIO_PINx); #else - gpio_af_set(SPI_GPIOx, GPIO_AF_0, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - gpio_mode_set(SPI_GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - + gpio_mode_set(SPI_GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SPI_SCK_GPIO_PINx | SPI_MISO_GPIO_PINx | SPI_MOSI_GPIO_PINx); gpio_mode_set(SPI_NSS_GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SPI_NSS_GPIO_PINx); #endif } @@ -165,21 +180,27 @@ void gd32_spi_setDataMode(uint8_t nMode) { void gd32_spi_chipSelect(uint8_t nChipSelect) { s_nChipSelect = nChipSelect; + + if (nChipSelect == GD32_SPI_CS0) { + spi_nss_output_enable(SPI_PERIPH); + } else { + spi_nss_output_disable(SPI_PERIPH); + } } void gd32_spi_transfernb(const char *pTxBuffer, char *pRxBuffer, uint32_t nDataLength) { assert(pTxBuffer != nullptr); assert(pRxBuffer != nullptr); - _cs_low(); + cs_low(); while (nDataLength-- > 0) { - *pRxBuffer = _send_byte(static_cast(*pTxBuffer)); + *pRxBuffer = send_byte(static_cast(*pTxBuffer)); pRxBuffer++; pTxBuffer++; } - _cs_high(); + cs_high(); } void gd32_spi_transfern(char *pTxBuffer, uint32_t nDataLength) { @@ -187,23 +208,23 @@ void gd32_spi_transfern(char *pTxBuffer, uint32_t nDataLength) { } void gd32_spi_write(const uint16_t nData) { - _cs_low(); + cs_low(); - _send_byte(static_cast(nData >> 8)); - _send_byte(static_cast(nData & 0xFF)); + send_byte(static_cast(nData >> 8)); + send_byte(static_cast(nData & 0xFF)); - _cs_high(); + cs_high(); } void gd32_spi_writenb(const char *pTxBuffer, uint32_t nDataLength) { assert(pTxBuffer != nullptr); - _cs_low(); + cs_low(); while (nDataLength-- > 0) { - _send_byte(static_cast(*pTxBuffer)); + send_byte(static_cast(*pTxBuffer)); pTxBuffer++; } - _cs_high(); + cs_high(); } diff --git a/lib-gd32/src/i2s_psc_config_dump.cpp b/lib-gd32/src/f/i2s_psc_config_dump.cpp similarity index 96% rename from lib-gd32/src/i2s_psc_config_dump.cpp rename to lib-gd32/src/f/i2s_psc_config_dump.cpp index e364ec2..e8d7235 100644 --- a/lib-gd32/src/i2s_psc_config_dump.cpp +++ b/lib-gd32/src/f/i2s_psc_config_dump.cpp @@ -45,7 +45,7 @@ #define RCU_CFG1_PREDV1_OFFSET 4U /* PREDV1 offset in RCU_CFG1 */ #define RCU_CFG1_PLL2MF_OFFSET 12U /* PLL2MF offset in RCU_CFG1 */ -void i2s_psc_config_dump(__attribute__((unused)) uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout) { +void i2s_psc_config_dump([[maybe_unused]] uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout) { uint32_t i2sdiv = 2U, i2sof = 0U; uint32_t clks = 0U; uint32_t i2sclock = 0U; diff --git a/lib-gd32/src/gd32_gpio_mode_set.cpp b/lib-gd32/src/gd32_gpio_mode_set.cpp new file mode 100644 index 0000000..bf8f480 --- /dev/null +++ b/lib-gd32/src/gd32_gpio_mode_set.cpp @@ -0,0 +1,75 @@ +#if defined (GD32F4XX) || defined (GD32H7XX) +/** + * @file gd32_gpio_mode_set.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "gd32.h" + +void gd32_gpio_mode_set_output(const uint32_t gpio_periph, const uint32_t pin) { + assert(pin != 0); + assert(__builtin_popcount(static_cast(pin)) == 1); + + auto ctl = GPIO_CTL(gpio_periph); + auto pupd = GPIO_PUD(gpio_periph); + + const auto i = 31 - __builtin_clz(pin); + + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, GPIO_MODE_OUTPUT); + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, GPIO_PUPD_NONE); + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +void gd32_gpio_mode_set_af(const uint32_t gpio_periph, const uint32_t pin) { + assert(pin != 0); + assert(__builtin_popcount(static_cast(pin)) == 1); + + auto ctl = GPIO_CTL(gpio_periph); + auto pupd = GPIO_PUD(gpio_periph); + + const auto i = 31 - __builtin_clz(pin); + + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, GPIO_MODE_AF); + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, GPIO_PUPD_PULLUP); + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} +#endif diff --git a/lib-gd32/src/gd32_pwm.cpp b/lib-gd32/src/gd32_pwm.cpp new file mode 100644 index 0000000..44c8da3 --- /dev/null +++ b/lib-gd32/src/gd32_pwm.cpp @@ -0,0 +1,300 @@ +/** + * @file gd32_pwm.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if 0 +#undef NDEBUG + +#define PWM_TIMERx TIMER2 +#define PWM_RCU_TIMERx RCU_TIMER2 + +#define TIMER2_FULL_REMAP +#define PWM_TIMER_REMAP TIMER2_REMAP +#define PWM_GPIO_AFx TIMER2_GPIO_AFx + +#define PWM_CH0_RCU_GPIOx TIMER2_CH0_RCU_GPIOx +#define PWM_CH0_GPIOx TIMER2_CH0_GPIOx +#define PWM_CH0_GPIO_PINx TIMER2_CH0_GPIO_PINx + +#define PWM_CH1_RCU_GPIOx TIMER2_CH1_RCU_GPIOx +#define PWM_CH1_GPIOx TIMER2_CH1_GPIOx +#define PWM_CH1_GPIO_PINx TIMER2_CH1_GPIO_PINx + +#define PWM_CH2_RCU_GPIOx TIMER2_CH2_RCU_GPIOx +#define PWM_CH2_GPIOx TIMER2_CH2_GPIOx +#define PWM_CH2_GPIO_PINx TIMER2_CH2_GPIO_PINx + +#define PWM_CH3_RCU_GPIOx TIMER2_CH3_RCU_GPIOx +#define PWM_CH3_GPIOx TIMER2_CH3_GPIOx +#define PWM_CH3_GPIO_PINx TIMER2_CH3_GPIO_PINx +#endif + +#include +#ifndef NDEBUG +# include +#endif + +#include "gd32_pwm.h" +#include "gd32.h" + +#include "debug.h" + +namespace pwm { +#if !defined(PWM_CHANNEL_0_DUTYCYCLE) +# define PWM_CHANNEL_0_DUTYCYCLE 50 +#endif +#if !defined(PWM_CHANNEL_1_DUTYCYCLE) +# define PWM_CHANNEL_1_DUTYCYCLE 50 +#endif +#if !defined(PWM_CHANNEL_2_DUTYCYCLE) +# define PWM_CHANNEL_2_DUTYCYCLE 50 +#endif +#if !defined(PWM_CHANNEL_3_DUTYCYCLE) +# define PWM_CHANNEL_3_DUTYCYCLE 50 +#endif +#if defined (PWM_CH0_RCU_GPIOx) +static constexpr uint32_t DEFAUL_CHANNEL_0_DUTYCYCLE = PWM_CHANNEL_0_DUTYCYCLE; +#endif +#if defined (PWM_CH1_RCU_GPIOx) +static constexpr uint32_t DEFAUL_CHANNEL_1_DUTYCYCLE = PWM_CHANNEL_1_DUTYCYCLE; +#endif +#if defined (PWM_CH2_RCU_GPIOx) +static constexpr uint32_t DEFAUL_CHANNEL_2_DUTYCYCLE = PWM_CHANNEL_2_DUTYCYCLE; +#endif +#if defined (PWM_CH3_RCU_GPIOx) +static constexpr uint32_t DEFAUL_CHANNEL_3_DUTYCYCLE = PWM_CHANNEL_3_DUTYCYCLE; +#endif +#if defined (PWM_RCU_TIMERx) && defined (PWM_TIMERx) +static constexpr uint32_t TIMER_PERIOD = 19999; // 50KHz +#endif +} // namespace pwm + +#if defined (PWM_RCU_TIMERx) && defined (PWM_TIMERx) + +static void dump() { +#if 1 + DEBUG_ENTRY +#ifndef NDEBUG + printf("PWM_TIMERx=0x%.8X\n", PWM_TIMERx - TIMER_BASE); + printf("PWM_RCU_TIMERx=0x%.8X\n", PWM_RCU_TIMERx); +# if defined (GPIO_INIT) + printf("PWM_TIMER_REMAP=0x%.8X\n", PWM_TIMER_REMAP); +# endif + puts("--------------------------------"); +# if defined (PWM_CH0_RCU_GPIOx) + printf("PWM_CH0_RCU_GPIOx=0x%.8X\n", PWM_CH0_RCU_GPIOx); + printf("PWM_CH0_GPIOx=0x%.8X\n", PWM_CH0_GPIOx); + printf("PWM_CH0_GPIO_PINx=0x%.4X\n", PWM_CH0_GPIO_PINx); + puts("--------------------------------"); +# endif +# if defined (PWM_CH1_RCU_GPIOx) + printf("PWM_CH1_RCU_GPIOx=0x%.8X\n", PWM_CH1_RCU_GPIOx); + printf("PWM_CH1_GPIOx=0x%.8X\n", PWM_CH1_GPIOx); + printf("PWM_CH1_GPIO_PINx=0x%.4X\n", PWM_CH1_GPIO_PINx); + puts("--------------------------------"); +# endif +# if defined (PWM_CH2_RCU_GPIOx) + printf("PWM_CH2_RCU_GPIOx=0x%.8X\n", PWM_CH2_RCU_GPIOx); + printf("PWM_CH2_GPIOx=0x%.8X\n", PWM_CH2_GPIOx); + printf("PWM_CH2_GPIO_PINx=0x%.4X\n", PWM_CH2_GPIO_PINx); + puts("--------------------------------"); +# endif +# if defined (PWM_CH3_RCU_GPIOx) + printf("PWM_CH3_RCU_GPIOx=0x%.8X\n", PWM_CH3_RCU_GPIOx); + printf("PWM_CH3_GPIOx=0x%.8X\n", PWM_CH3_GPIOx); + printf("PWM_CH3_GPIO_PINx=0x%.4X\n", PWM_CH3_GPIO_PINx); +# endif +#endif + DEBUG_EXIT +#endif +} + +static void gpio_config() { +#if defined (PWM_CH0_RCU_GPIOx) + rcu_periph_clock_enable(PWM_CH0_RCU_GPIOx); +#endif +#if defined (PWM_CH1_RCU_GPIOx) + rcu_periph_clock_enable(PWM_CH1_RCU_GPIOx); +#endif +#if defined (PWM_CH2_RCU_GPIOx) + rcu_periph_clock_enable(PWM_CH2_RCU_GPIOx); +#endif +#if defined (PWM_CH3_RCU_GPIOx) + rcu_periph_clock_enable(PWM_CH3_RCU_GPIOx); +#endif + +#if defined (GPIO_INIT) + rcu_periph_clock_enable(RCU_AF); +# if defined(PWM_TIMER_REMAP) + gpio_pin_remap_config(PWM_TIMER_REMAP, ENABLE); +# endif +# if defined (PWM_CH0_GPIOx) && defined (PWM_CH0_GPIO_PINx) + gpio_init(PWM_CH0_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWM_CH0_GPIO_PINx); +# endif +# if defined (PWM_CH1_GPIOx) && defined (PWM_CH1_GPIO_PINx) + gpio_init(PWM_CH1_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWM_CH1_GPIO_PINx); +# endif +# if defined (PWM_CH2_GPIOx) && defined (PWM_CH2_GPIO_PINx) + gpio_init(PWM_CH2_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWM_CH2_GPIO_PINx); +# endif +# if defined (PWM_CH3_GPIOx) && defined (PWM_CH3_GPIO_PINx) + gpio_init(PWM_CH3_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PWM_CH3_GPIO_PINx); +# endif +#else +# if defined (PWM_CH0_GPIOx) && defined (PWM_CH0_GPIO_PINx) + gpio_af_set(PWM_CH0_GPIOx, PWM_GPIO_AFx, PWM_CH0_GPIO_PINx); + gpio_mode_set(PWM_CH0_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM_CH0_GPIO_PINx); + gpio_output_options_set(PWM_CH0_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, PWM_CH0_GPIO_PINx); +# endif +# if defined (PWM_CH1_GPIOx) && defined (PWM_CH1_GPIO_PINx) + gpio_af_set(PWM_CH1_GPIOx, PWM_GPIO_AFx, PWM_CH1_GPIO_PINx); + gpio_mode_set(PWM_CH1_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM_CH1_GPIO_PINx); + gpio_output_options_set(PWM_CH1_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, PWM_CH1_GPIO_PINx); +# endif +# if defined (PWM_CH2_GPIOx) && defined (PWM_CH2_GPIO_PINx) + gpio_af_set(PWM_CH2_GPIOx, PWM_GPIO_AFx, PWM_CH2_GPIO_PINx); + gpio_mode_set(PWM_CH2_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM_CH2_GPIO_PINx); + gpio_output_options_set(PWM_CH2_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, PWM_CH2_GPIO_PINx); +# endif +# if defined (PWM_CH3_GPIOx) && defined (PWM_CH3_GPIO_PINx) + gpio_af_set(PWM_CH3_GPIOx, PWM_GPIO_AFx, PWM_CH3_GPIO_PINx); + gpio_mode_set(PWM_CH3_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, PWM_CH3_GPIO_PINx); + gpio_output_options_set(PWM_CH3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, PWM_CH3_GPIO_PINx); +# endif +#endif +} + +static void timer_config() { +#if defined (PWM_RCU_TIMERx) && defined (PWM_TIMERx) + rcu_periph_clock_enable(PWM_RCU_TIMERx); + + timer_deinit(PWM_TIMERx); + + timer_parameter_struct timer_initpara; + timer_initpara.prescaler = TIMER_PSC_1MHZ; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = pwm::TIMER_PERIOD; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + timer_init(PWM_TIMERx, &timer_initpara); + +# if defined (PWM_CH0_RCU_GPIOx) || defined (PWM_CH1_RCU_GPIOx) || defined (PWM_CH2_RCU_GPIOx) || defined (PWM_CH3_RCU_GPIOx) + timer_oc_parameter_struct timer_ocintpara; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.outputstate = TIMER_CCX_ENABLE; + timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH; + timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE; + timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW; + timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +# endif +# if defined (PWM_CH0_RCU_GPIOx) + timer_channel_output_config(PWM_TIMERx, TIMER_CH_0, &timer_ocintpara); + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_0, 1999); + timer_channel_output_mode_config(PWM_TIMERx, TIMER_CH_0, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(PWM_TIMERx, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE); +# endif +# if defined (PWM_CH1_RCU_GPIOx) + timer_channel_output_config(PWM_TIMERx, TIMER_CH_1, &timer_ocintpara); + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_1, 3999); + timer_channel_output_mode_config(PWM_TIMERx, TIMER_CH_1, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(PWM_TIMERx, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE); +# endif +# if defined (PWM_CH2_RCU_GPIOx) + timer_channel_output_config(PWM_TIMERx, TIMER_CH_2, &timer_ocintpara); + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_2, 7999); + timer_channel_output_mode_config(PWM_TIMERx, TIMER_CH_2, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(PWM_TIMERx, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE); +# endif +# if defined (PWM_CH3_RCU_GPIOx) + timer_channel_output_config(PWM_TIMERx, TIMER_CH_3, &timer_ocintpara); + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_3, 11999); + timer_channel_output_mode_config(PWM_TIMERx, TIMER_CH_3, TIMER_OC_MODE_PWM0); + timer_channel_output_shadow_config(PWM_TIMERx, TIMER_CH_3, TIMER_OC_SHADOW_DISABLE); +# endif + + timer_auto_reload_shadow_enable(PWM_TIMERx); + timer_enable(PWM_TIMERx); +#endif +} + +void gd32_pwm_begin() { + DEBUG_ENTRY + + dump(); + + gpio_config(); + timer_config(); + +#if defined (PWM_CH0_RCU_GPIOx) + gd32_pwm_set_duty_cycle(pwm::Channel::PWM_CHANNEL_0, pwm::DEFAUL_CHANNEL_0_DUTYCYCLE); +#endif +#if defined (PWM_CH1_RCU_GPIOx) + gd32_pwm_set_duty_cycle(pwm::Channel::PWM_CHANNEL_1, pwm::DEFAUL_CHANNEL_1_DUTYCYCLE); +#endif +#if defined (PWM_CH2_RCU_GPIOx) + gd32_pwm_set_duty_cycle(pwm::Channel::PWM_CHANNEL_2, pwm::DEFAUL_CHANNEL_2_DUTYCYCLE); +#endif +#if defined (PWM_CH3_RCU_GPIOx) + gd32_pwm_set_duty_cycle(pwm::Channel::PWM_CHANNEL_3, pwm::DEFAUL_CHANNEL_3_DUTYCYCLE); +#endif + + DEBUG_EXIT +} + +void gd32_pwm_set_duty_cycle(const pwm::Channel channel, const uint32_t nDutyCycle) { + DEBUG_ENTRY + + const uint32_t nPulse = (nDutyCycle > 100 ? 100 : nDutyCycle) * (pwm::TIMER_PERIOD / 100U); + + DEBUG_PRINTF("Channel=%u, nDutyCycle=%u, nPulse=%u", static_cast(channel), nDutyCycle, static_cast(nPulse)); + + switch (channel) { +#if defined (PWM_CH0_RCU_GPIOx) + case pwm::Channel::PWM_CHANNEL_0: + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_0, nPulse); + break; +#endif +#if defined (PWM_CH1_RCU_GPIOx) + case pwm::Channel::PWM_CHANNEL_1: + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_1, nPulse); + break; +#endif +#if defined (PWM_CH2_RCU_GPIOx) + case pwm::Channel::PWM_CHANNEL_2: + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_2, nPulse); + break; +#endif +#if defined (PWM_CH3_RCU_GPIOx) + case pwm::Channel::PWM_CHANNEL_3: + timer_channel_output_pulse_value_config(PWM_TIMERx, TIMER_CH_3, nPulse); + break; +#endif + default: + break; + } + + DEBUG_EXIT +} +#endif diff --git a/lib-gd32/src/gd32_spi_dma_i2s.cpp b/lib-gd32/src/gd32_spi_dma_i2s.cpp index e25feda..6ddfbd5 100644 --- a/lib-gd32/src/gd32_spi_dma_i2s.cpp +++ b/lib-gd32/src/gd32_spi_dma_i2s.cpp @@ -2,7 +2,7 @@ * @file gd32_spi_dma_i2s.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,143 +28,156 @@ #include "gd32.h" -#if defined (GD32F4XX) -# define DMA_PARAMETER_STRUCT dma_single_data_parameter_struct -# define DMA_CHMADDR DMA_CHM0ADDR -# define DMA_MEMORY_TO_PERIPHERAL DMA_MEMORY_TO_PERIPH -# define DMA_PERIPHERAL_WIDTH_16BIT DMA_PERIPH_WIDTH_16BIT -# define dma_init dma_single_data_mode_init -# define dma_struct_para_init dma_single_data_para_struct_init -# define dma_memory_to_memory_disable(x,y) +#if defined (I2S_PERIPH) + +# if defined (GD32H7XX) + static_assert(I2S_PERIPH != SPI3); + static_assert(I2S_PERIPH != SPI4); +# else + static_assert(I2S_PERIPH != SPI0); +# endif + +# if defined (GD32F4XX) || defined (GD32H7XX) +# define DMA_PARAMETER_STRUCT dma_single_data_parameter_struct +# define DMA_CHMADDR DMA_CHM0ADDR +# define DMA_MEMORY_TO_PERIPHERAL DMA_MEMORY_TO_PERIPH +# define DMA_PERIPHERAL_WIDTH_16BIT DMA_PERIPH_WIDTH_16BIT +# define dma_init dma_single_data_mode_init +# define dma_struct_para_init dma_single_data_para_struct_init +# define dma_memory_to_memory_disable(x,y) +# else +# define DMA_PARAMETER_STRUCT dma_parameter_struct +# endif + +# ifndef NDEBUG +# if !defined (GD32H7XX) + void i2s_psc_config_dump(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout); +# endif +# endif + +# if !defined(SPI_BUFFER_SIZE) +# define SPI_BUFFER_SIZE ((24 * 1024) / 2) +# endif + +static uint16_t s_TxBuffer[SPI_BUFFER_SIZE] __attribute__ ((aligned (4))); + +static void rcu_config() { + rcu_periph_clock_enable(I2S_WS_RCU_GPIOx); + +#if defined (GPIO_INIT) + rcu_periph_clock_enable(RCU_AF); + rcu_periph_clock_enable(I2S_RCU_SPIx); + rcu_periph_clock_enable(I2S_RCU_GPIOx); #else -# define DMA_PARAMETER_STRUCT dma_parameter_struct + rcu_periph_clock_enable(I2S_CK_RCU_GPIOx); + rcu_periph_clock_enable(I2S_SD_RCU_GPIOx); #endif -#ifndef NDEBUG -void i2s_psc_config_dump(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout); -#endif + if (I2S_DMAx == DMA0) { + rcu_periph_clock_enable(RCU_DMA0); + } else { + rcu_periph_clock_enable(RCU_DMA1); + } -#if !defined(SPI_BUFFER_SIZE) -# define SPI_BUFFER_SIZE ((24 * 1024) / 2) +#if defined (GD32H7XX) + rcu_periph_clock_enable(RCU_DMAMUX); #endif +} -static uint16_t s_TxBuffer[SPI_BUFFER_SIZE] __attribute__ ((aligned (4))); +static void gpio_config() { +#if defined (GPIO_INIT) +# if defined (I2S_REMAP_GPIO) + gpio_pin_remap_config(I2S_REMAP_GPIO, ENABLE); + if (I2S_PERIPH == SPI0) { + gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); + } +# else + if (I2S_PERIPH == SPI2) { + gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); + } +# endif + gpio_init(I2S_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, I2S_CK_GPIO_PINx | I2S_SD_GPIO_PINx); + gpio_init(I2S_WS_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, I2S_WS_GPIO_PINx); +#else + gpio_af_set(I2S_CK_GPIOx, I2S_GPIO_AFx, I2S_CK_GPIO_PINx); + gpio_mode_set(I2S_CK_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, I2S_CK_GPIO_PINx); + gpio_output_options_set(I2S_CK_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, I2S_CK_GPIO_PINx); + + gpio_af_set(I2S_SD_GPIOx, I2S_GPIO_AFx, I2S_SD_GPIO_PINx); + gpio_mode_set(I2S_SD_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, I2S_SD_GPIO_PINx); + gpio_output_options_set(I2S_SD_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, I2S_SD_GPIO_PINx); -static void _spi_i2s_dma_config() { - rcu_periph_clock_enable(RCU_DMA1); + gpio_af_set(I2S_WS_GPIOx, I2S_GPIO_AFx, I2S_WS_GPIO_PINx); + gpio_mode_set(I2S_WS_GPIOx, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, I2S_WS_GPIO_PINx); + gpio_output_options_set(I2S_WS_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, I2S_WS_GPIO_PINx); +#endif +} - dma_deinit(SPI_DMAx, SPI_DMA_CHx); +static void spi_i2s_dma_config() { + dma_deinit(I2S_DMAx, I2S_DMA_CHx); DMA_PARAMETER_STRUCT dma_init_struct; dma_struct_para_init(&dma_init_struct); + +#if defined (GD32H7XX) + dma_init_struct.request = I2S_DMA_REQUEST_I2S_TX; +#endif dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; -#if !defined (GD32F4XX) +# if defined (GD32F4XX) || defined (GD32H7XX) +# else dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT; #endif - dma_init_struct.periph_addr = SPI_PERIPH + 0x0CU; - dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; -#if !defined (GD32F4XX) - dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; +#if defined (GD32H7XX) + dma_init_struct.periph_addr = (uint32_t)&SPI_TDATA(I2S_PERIPH); #else + dma_init_struct.periph_addr = I2S_PERIPH + 0x0CU; +#endif + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; +#if defined (GD32F4XX) || defined (GD32H7XX) dma_init_struct.periph_memory_width = DMA_PERIPHERAL_WIDTH_16BIT; +#else + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; #endif dma_init_struct.priority = DMA_PRIORITY_HIGH; - dma_init(SPI_DMAx, SPI_DMA_CHx, &dma_init_struct); - /* configure DMA mode */ - dma_circulation_disable(SPI_DMAx, SPI_DMA_CHx); - dma_memory_to_memory_disable(SPI_DMAx, SPI_DMA_CHx); + dma_init(I2S_DMAx, I2S_DMA_CHx, &dma_init_struct); + + dma_circulation_disable(I2S_DMAx, I2S_DMA_CHx); + dma_memory_to_memory_disable(I2S_DMAx, I2S_DMA_CHx); #if defined (GD32F4XX) - dma_channel_subperipheral_select(SPI_DMAx, SPI_DMA_CHx, SPI_DMA_SUBPERIx); + dma_channel_subperipheral_select(I2S_DMAx, I2S_DMA_CHx, I2S_DMA_SUBPERIx); #endif - DMA_CHCNT(SPI_DMAx, SPI_DMA_CHx) = 0; + DMA_CHCNT(I2S_DMAx, I2S_DMA_CHx) = 0; } - +namespace i2s { void gd32_spi_dma_begin() { - assert(SPI_PERIPH != SPI0); - - rcu_periph_clock_enable(SPI_NSS_RCU_GPIOx); - rcu_periph_clock_enable(SPI_RCU_GPIOx); - rcu_periph_clock_enable(SPI_RCU_CLK); - -#if !defined (GD32F4XX) - rcu_periph_clock_enable(RCU_AF); - - gpio_init(SPI_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - gpio_init(SPI_NSS_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPI_NSS_GPIO_PINx); - -# if defined (SPI2_REMAP) - gpio_pin_remap_config(GPIO_SPI2_REMAP, ENABLE); -# else - if (SPI_PERIPH == SPI2) { - gpio_pin_remap_config(GPIO_SWJ_DISABLE_REMAP, ENABLE); - } -# endif -#else - if (SPI_PERIPH == SPI2) { - gpio_af_set(SPI_GPIOx, GPIO_AF_6, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - } else { - gpio_af_set(SPI_GPIOx, GPIO_AF_5, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - } - gpio_mode_set(SPI_GPIOx, GPIO_MODE_AF, GPIO_PUPD_NONE, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - gpio_output_options_set(SPI_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN); - - gpio_mode_set(SPI_NSS_GPIOx, GPIO_MODE_OUTPUT,GPIO_PUPD_NONE, SPI_NSS_GPIO_PINx); - gpio_output_options_set(SPI_NSS_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SPI_NSS_GPIO_PINx); -#endif - -#if defined (GD32F10X_CL) || defined (GD32F20X_CL) - /** - * Setup PLL2 - * - * i2sclock=160000000 - * i2sdiv=12, i2sof=256 - */ - - RCU_CTL &= ~RCU_CTL_PLL2EN; - - rcu_pll2_config(RCU_PLL2_MUL16); + rcu_config(); + gpio_config(); - RCU_CTL |= RCU_CTL_PLL2EN; + i2s_disable(I2S_PERIPH); + i2s_psc_config(I2S_PERIPH, 200000, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); + i2s_init(I2S_PERIPH, I2S_MODE_MASTERTX, I2S_STD_MSB, I2S_CKPL_LOW); + i2s_enable(I2S_PERIPH); - while ((RCU_CTL & RCU_CTL_PLL2STB) == 0U) { - } - - if (SPI_PERIPH == SPI2) { - rcu_i2s2_clock_config(RCU_I2S2SRC_CKPLL2_MUL2); - } else { - rcu_i2s1_clock_config(RCU_I2S1SRC_CKPLL2_MUL2); - } -#endif - - i2s_disable(SPI_PERIPH); - i2s_psc_config(SPI_PERIPH, 200000, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); - i2s_init(SPI_PERIPH, I2S_MODE_MASTERTX, I2S_STD_MSB, I2S_CKPL_LOW); - i2s_enable(SPI_PERIPH); - - _spi_i2s_dma_config(); + spi_i2s_dma_config(); #ifndef NDEBUG - i2s_psc_config_dump(SPI_PERIPH, 200000, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); + i2s_psc_config_dump(I2S_PERIPH, 200000, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); #endif } void gd32_spi_dma_set_speed_hz(uint32_t nSpeedHz) { - const auto audiosample = nSpeedHz / 16 / 2 ; + const auto audiosample = nSpeedHz / 16U / 2U ; - i2s_disable(SPI_PERIPH); - i2s_psc_config(SPI2, audiosample, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); - i2s_enable(SPI_PERIPH); + i2s_disable(I2S_PERIPH); + i2s_psc_config(I2S_PERIPH, audiosample, I2S_FRAMEFORMAT_DT16B_CH16B, I2S_MCKOUT_DISABLE); + i2s_enable(I2S_PERIPH); } -/** - * DMA - */ - const uint8_t *gd32_spi_dma_tx_prepare(uint32_t *nLength) { *nLength = (sizeof(s_TxBuffer) / sizeof(s_TxBuffer[0])) * 2; - return (const uint8_t*) s_TxBuffer; + return (const uint8_t *) s_TxBuffer; } void gd32_spi_dma_tx_start(const uint8_t *pTxBuffer, uint32_t nLength) { @@ -172,24 +185,27 @@ void gd32_spi_dma_tx_start(const uint8_t *pTxBuffer, uint32_t nLength) { assert((uint32_t )pTxBuffer >= (uint32_t )s_TxBuffer); assert(nLength != 0); +#if defined (GD32F4XX) || defined (GD32H7XX) + dma_flag_clear(I2S_DMAx, I2S_DMA_CHx, DMA_FLAG_FTF); +#endif + const auto dma_chcnt = (((nLength + 1) / 2) & DMA_CHXCNT_CNT); - auto nDmaChCTL = DMA_CHCTL(SPI_DMAx, SPI_DMA_CHx); + auto nDmaChCTL = DMA_CHCTL(I2S_DMAx, I2S_DMA_CHx); nDmaChCTL &= ~DMA_CHXCTL_CHEN; - DMA_CHCTL(SPI_DMAx, SPI_DMA_CHx) = nDmaChCTL; - DMA_CHMADDR(SPI_DMAx, SPI_DMA_CHx) = (uint32_t)pTxBuffer; - DMA_CHCNT(SPI_DMAx, SPI_DMA_CHx) = dma_chcnt; + DMA_CHCTL(I2S_DMAx, I2S_DMA_CHx) = nDmaChCTL; + + DMA_CHMADDR(I2S_DMAx, I2S_DMA_CHx) = (uint32_t)pTxBuffer; + DMA_CHCNT(I2S_DMAx, I2S_DMA_CHx) = dma_chcnt; + nDmaChCTL |= DMA_CHXCTL_CHEN; - DMA_CHCTL(SPI_DMAx, SPI_DMA_CHx) = nDmaChCTL; - spi_dma_enable(SPI_PERIPH, SPI_DMA_TRANSMIT); -} + DMA_CHCTL(I2S_DMAx, I2S_DMA_CHx) = nDmaChCTL; -bool gd32_spi_dma_tx_is_active(void) { - return (uint32_t) DMA_CHCNT(SPI_DMAx, SPI_DMA_CHx) != 0; + spi_dma_enable(I2S_PERIPH, SPI_DMA_TRANSMIT); } -/** - * /CS - */ - -//TODO Implement /CS +bool gd32_spi_dma_tx_is_active() { + return DMA_CHCNT(I2S_DMAx, I2S_DMA_CHx) != 0; +} +} // namespace i2s +#endif diff --git a/lib-gd32/src/gd32_uart.cpp b/lib-gd32/src/gd32_uart.cpp index 7620cdd..41ef6a8 100644 --- a/lib-gd32/src/gd32_uart.cpp +++ b/lib-gd32/src/gd32_uart.cpp @@ -2,7 +2,7 @@ * @file gd32_uart.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,51 +29,51 @@ #include "gd32_uart.h" #include "gd32.h" -static void _rcu_periph_clock_enable(const uint32_t usart_periph) { +static void rcu_config(const uint32_t usart_periph) { #ifndef NDEBUG bool isSet = false; #endif switch (usart_periph) { case USART0: - rcu_periph_clock_enable(USART0_RCU_CLK); - rcu_periph_clock_enable(USART0_GPIO_CLK); + rcu_periph_clock_enable(USART0_RCU_USART0); + rcu_periph_clock_enable(USART0_RCU_GPIOx); #ifndef NDEBUG isSet = true; #endif break; case USART1: - rcu_periph_clock_enable(USART1_RCU_CLK); - rcu_periph_clock_enable(USART1_GPIO_CLK); + rcu_periph_clock_enable(USART1_RCU_USART1); + rcu_periph_clock_enable(USART1_RCU_GPIOx); #ifndef NDEBUG isSet = true; #endif break; case USART2: - rcu_periph_clock_enable(USART2_RCU_CLK); - rcu_periph_clock_enable(USART2_GPIO_CLK); + rcu_periph_clock_enable(USART2_RCU_USART2); + rcu_periph_clock_enable(USART2_RCU_GPIOx); #ifndef NDEBUG isSet = true; #endif break; case UART3: - rcu_periph_clock_enable(UART3_RCU_CLK); - rcu_periph_clock_enable(UART3_GPIO_CLK); + rcu_periph_clock_enable(UART3_RCU_UART3); + rcu_periph_clock_enable(UART3_RCU_GPIOx); #ifndef NDEBUG isSet = true; #endif break; case UART4: - rcu_periph_clock_enable(UART4_RCU_CLK); - rcu_periph_clock_enable(UART4_GPIO_TX_CLK); - rcu_periph_clock_enable(UART4_GPIO_RX_CLK); + rcu_periph_clock_enable(UART4_RCU_UART4); + rcu_periph_clock_enable(UART4_TX_RCU_GPIOx); + rcu_periph_clock_enable(UART4_RX_RCU_GPIOx); #ifndef NDEBUG isSet = true; #endif break; #if defined (USART5) case USART5: - rcu_periph_clock_enable(USART5_RCU_CLK); - rcu_periph_clock_enable(USART5_GPIO_CLK); + rcu_periph_clock_enable(USART5_RCU_USART5); + rcu_periph_clock_enable(USART5_RCU_GPIOx); # ifndef NDEBUG isSet = true; # endif @@ -81,8 +81,8 @@ static void _rcu_periph_clock_enable(const uint32_t usart_periph) { #endif #if defined (UART6) case UART6: - rcu_periph_clock_enable(UART6_RCU_CLK); - rcu_periph_clock_enable(UART6_GPIO_CLK); + rcu_periph_clock_enable(UART6_RCU_UART6); + rcu_periph_clock_enable(UART6_RCU_GPIOx); # ifndef NDEBUG isSet = true; # endif @@ -90,8 +90,8 @@ static void _rcu_periph_clock_enable(const uint32_t usart_periph) { #endif #if defined (UART7) case UART7: - rcu_periph_clock_enable(UART7_RCU_CLK); - rcu_periph_clock_enable(UART7_GPIO_CLK); + rcu_periph_clock_enable(UART7_RCU_UART7); + rcu_periph_clock_enable(UART7_RCU_GPIOx); # ifndef NDEBUG isSet = true; # endif @@ -106,28 +106,28 @@ static void _rcu_periph_clock_enable(const uint32_t usart_periph) { assert(isSet); } -#if !defined (GD32F4XX) -static void _gpio_init(const uint32_t usart_periph) { +#if !(defined (GD32F4XX) || defined (GD32H7XX)) +static void gpio_config(const uint32_t usart_periph) { rcu_periph_clock_enable(RCU_AF); switch (usart_periph) { case USART0: - gpio_init(USART0_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART0_TX_PIN); - gpio_init(USART0_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART0_RX_PIN); + gpio_init(USART0_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART0_TX_GPIO_PINx); + gpio_init(USART0_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART0_RX_GPIO_PINx); #if defined (USART0_REMAP) gpio_pin_remap_config(GPIO_USART0_REMAP, ENABLE); #endif break; case USART1: - gpio_init(USART1_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART1_TX_PIN); - gpio_init(USART1_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART1_RX_PIN); + gpio_init(USART1_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART1_TX_GPIO_PINx); + gpio_init(USART1_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART1_RX_GPIO_PINx); #if defined (USART1_REMAP) gpio_pin_remap_config(GPIO_USART1_REMAP, ENABLE); #endif break; case USART2: - gpio_init(USART2_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART2_TX_PIN); - gpio_init(USART2_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART2_RX_PIN); + gpio_init(USART2_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART2_TX_GPIO_PINx); + gpio_init(USART2_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART2_RX_GPIO_PINx); #if defined (USART2_FULL_REMAP) gpio_pin_remap_config(GPIO_USART2_FULL_REMAP, ENABLE); #elif defined (USART2_PARTIAL_REMAP) @@ -135,20 +135,20 @@ static void _gpio_init(const uint32_t usart_periph) { #endif break; case UART3: - gpio_init(UART3_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART3_TX_PIN); - gpio_init(UART3_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART3_RX_PIN); + gpio_init(UART3_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART3_TX_GPIO_PINx); + gpio_init(UART3_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART3_RX_GPIO_PINx); #if defined (UART3_REMAP) gpio_pin_remap_config(GPIO_PCF5_UART3_REMAP, ENABLE); #endif break; case UART4: - gpio_init(UART4_GPIO_TX_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART4_TX_PIN); - gpio_init(UART4_GPIO_RX_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART4_RX_PIN); + gpio_init(UART4_TX_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART4_TX_GPIO_PINx); + gpio_init(UART4_RX_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART4_RX_GPIO_PINx); break; #if defined (USART5) case USART5: - gpio_init(USART5_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART5_TX_PIN); - gpio_init(USART5_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART5_RX_PIN); + gpio_init(USART5_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, USART5_TX_GPIO_PINx); + gpio_init(USART5_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, USART5_RX_GPIO_PINx); # if defined (USART5_REMAP) gpio_pin_remap_config(GPIO_PCF5_USART5_TX_PG14_REMAP, ENABLE); gpio_pin_remap_config(GPIO_PCF5_USART5_RX_PG9_REMAP, ENABLE); @@ -157,8 +157,8 @@ static void _gpio_init(const uint32_t usart_periph) { #endif #if defined (UART6) case UART6: - gpio_init(UART6_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART6_TX_PIN); - gpio_init(UART6_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART6_RX_PIN); + gpio_init(UART6_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART6_TX_GPIO_PINx); + gpio_init(UART6_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART6_RX_GPIO_PINx); # if defined (UART6_REMAP) gpio_pin_remap_config(GPIO_PCF5_UART6_REMAP, ENABLE); # endif @@ -166,8 +166,8 @@ static void _gpio_init(const uint32_t usart_periph) { #endif #if defined (UART7) case UART7: - gpio_init(UART7_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART7_TX_PIN); - gpio_init(UART7_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART7_RX_PIN); + gpio_init(UART7_GPIOx, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, UART7_TX_GPIO_PINx); + gpio_init(UART7_GPIOx, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, UART7_RX_GPIO_PINx); break; #endif default: @@ -177,77 +177,77 @@ static void _gpio_init(const uint32_t usart_periph) { } } #else -void _gpio_init(const uint32_t usart_periph) { +static void gpio_config(const uint32_t usart_periph) { switch (usart_periph) { case USART0: - gpio_af_set(USART0_GPIO_PORT, GPIO_AF_7, USART0_TX_PIN); - gpio_mode_set(USART0_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART0_TX_PIN); - gpio_output_options_set(USART0_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART0_TX_PIN); - gpio_af_set(USART0_GPIO_PORT, GPIO_AF_7, USART0_RX_PIN); - gpio_mode_set(USART0_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART0_RX_PIN); - gpio_output_options_set(USART0_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART0_RX_PIN); + gpio_af_set(USART0_GPIOx, USART0_GPIO_AFx, USART0_TX_GPIO_PINx); + gpio_mode_set(USART0_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART0_TX_GPIO_PINx); + gpio_output_options_set(USART0_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART0_TX_GPIO_PINx); + gpio_af_set(USART0_GPIOx, USART0_GPIO_AFx, USART0_RX_GPIO_PINx); + gpio_mode_set(USART0_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART0_RX_GPIO_PINx); + gpio_output_options_set(USART0_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART0_RX_GPIO_PINx); break; case USART1: - gpio_af_set(USART1_GPIO_PORT, GPIO_AF_7, USART1_TX_PIN); - gpio_mode_set(USART1_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART1_TX_PIN); - gpio_output_options_set(USART1_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART1_TX_PIN); - gpio_af_set(USART1_GPIO_PORT, GPIO_AF_7, USART1_RX_PIN); - gpio_mode_set(USART1_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART1_RX_PIN); - gpio_output_options_set(USART1_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART1_RX_PIN); + gpio_af_set(USART1_GPIOx, USART1_GPIO_AFx, USART1_TX_GPIO_PINx); + gpio_mode_set(USART1_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART1_TX_GPIO_PINx); + gpio_output_options_set(USART1_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART1_TX_GPIO_PINx); + gpio_af_set(USART1_GPIOx, USART1_GPIO_AFx, USART1_RX_GPIO_PINx); + gpio_mode_set(USART1_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART1_RX_GPIO_PINx); + gpio_output_options_set(USART1_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART1_RX_GPIO_PINx); break; case USART2: - gpio_af_set(USART2_GPIO_PORT, GPIO_AF_7, USART2_TX_PIN); - gpio_mode_set(USART2_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART2_TX_PIN); - gpio_output_options_set(USART2_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART2_TX_PIN); - gpio_af_set(USART2_GPIO_PORT, GPIO_AF_7, USART2_RX_PIN); - gpio_mode_set(USART2_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART2_RX_PIN); - gpio_output_options_set(USART2_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART2_RX_PIN); + gpio_af_set(USART2_GPIOx, USART2_GPIO_AFx, USART2_TX_GPIO_PINx); + gpio_mode_set(USART2_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART2_TX_GPIO_PINx); + gpio_output_options_set(USART2_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART2_TX_GPIO_PINx); + gpio_af_set(USART2_GPIOx, USART2_GPIO_AFx, USART2_RX_GPIO_PINx); + gpio_mode_set(USART2_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART2_RX_GPIO_PINx); + gpio_output_options_set(USART2_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART2_RX_GPIO_PINx); break; case UART3: - gpio_af_set(UART3_GPIO_PORT, GPIO_AF_8, UART3_TX_PIN); - gpio_mode_set(UART3_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART3_TX_PIN); - gpio_output_options_set(UART3_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART3_TX_PIN); - gpio_af_set(UART3_GPIO_PORT, GPIO_AF_8, UART3_RX_PIN); - gpio_mode_set(UART3_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART3_RX_PIN); - gpio_output_options_set(UART3_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART3_RX_PIN); + gpio_af_set(UART3_GPIOx, UART3_GPIO_AFx, UART3_TX_GPIO_PINx); + gpio_mode_set(UART3_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART3_TX_GPIO_PINx); + gpio_output_options_set(UART3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART3_TX_GPIO_PINx); + gpio_af_set(UART3_GPIOx, UART3_GPIO_AFx, UART3_RX_GPIO_PINx); + gpio_mode_set(UART3_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART3_RX_GPIO_PINx); + gpio_output_options_set(UART3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART3_RX_GPIO_PINx); break; case UART4: - gpio_af_set(UART4_GPIO_TX_PORT, GPIO_AF_8, UART4_TX_PIN); - gpio_mode_set(UART4_GPIO_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART4_TX_PIN); - gpio_output_options_set(UART4_GPIO_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART4_TX_PIN); - gpio_af_set(UART4_GPIO_RX_PORT, GPIO_AF_8, UART4_RX_PIN); - gpio_mode_set(UART4_GPIO_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART4_RX_PIN); - gpio_output_options_set(UART4_GPIO_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART4_RX_PIN); + gpio_af_set(UART4_TX_GPIOx, UART4_GPIO_AFx, UART4_TX_GPIO_PINx); + gpio_mode_set(UART4_TX_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART4_TX_GPIO_PINx); + gpio_output_options_set(UART4_TX_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART4_TX_GPIO_PINx); + gpio_af_set(UART4_RX_GPIOx, UART4_GPIO_AFx, UART4_RX_GPIO_PINx); + gpio_mode_set(UART4_RX_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART4_RX_GPIO_PINx); + gpio_output_options_set(UART4_RX_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART4_RX_GPIO_PINx); break; #if defined (USART5) case USART5: - gpio_af_set(USART5_GPIO_PORT, GPIO_AF_8, USART5_TX_PIN); - gpio_mode_set(USART5_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART5_TX_PIN); - gpio_output_options_set(USART5_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART5_TX_PIN); - gpio_af_set(USART5_GPIO_PORT, GPIO_AF_8, USART5_RX_PIN); - gpio_mode_set(USART5_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART5_RX_PIN); - gpio_output_options_set(USART5_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, USART5_RX_PIN); + gpio_af_set(USART5_GPIOx, USART5_GPIO_AFx, USART5_TX_GPIO_PINx); + gpio_mode_set(USART5_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART5_TX_GPIO_PINx); + gpio_output_options_set(USART5_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART5_TX_GPIO_PINx); + gpio_af_set(USART5_GPIOx, USART5_GPIO_AFx, USART5_RX_GPIO_PINx); + gpio_mode_set(USART5_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART5_RX_GPIO_PINx); + gpio_output_options_set(USART5_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, USART5_RX_GPIO_PINx); break; #endif #if defined (UART6) case UART6: - gpio_af_set(UART6_GPIO_PORT, GPIO_AF_8, UART6_TX_PIN); - gpio_mode_set(UART6_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART6_TX_PIN); - gpio_output_options_set(UART6_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART6_TX_PIN); - gpio_af_set(UART6_GPIO_PORT, GPIO_AF_8, UART6_RX_PIN); - gpio_mode_set(UART6_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART6_RX_PIN); - gpio_output_options_set(UART6_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART6_RX_PIN); + gpio_af_set(UART6_GPIOx, UART6_GPIO_AFx, UART6_TX_GPIO_PINx); + gpio_mode_set(UART6_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART6_TX_GPIO_PINx); + gpio_output_options_set(UART6_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART6_TX_GPIO_PINx); + gpio_af_set(UART6_GPIOx, UART6_GPIO_AFx, UART6_RX_GPIO_PINx); + gpio_mode_set(UART6_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART6_RX_GPIO_PINx); + gpio_output_options_set(UART6_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART6_RX_GPIO_PINx); break; #endif #if defined (UART7) case UART7: - gpio_af_set(UART7_GPIO_PORT, GPIO_AF_8, UART7_TX_PIN); - gpio_mode_set(UART7_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART7_TX_PIN); - gpio_output_options_set(UART7_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART7_TX_PIN); - gpio_af_set(UART7_GPIO_PORT, GPIO_AF_8, UART7_RX_PIN); - gpio_mode_set(UART7_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART7_RX_PIN); - gpio_output_options_set(UART7_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART7_RX_PIN); + gpio_af_set(UART7_GPIOx, UART7_GPIO_AFx, UART7_TX_GPIO_PINx); + gpio_mode_set(UART7_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART7_TX_GPIO_PINx); + gpio_output_options_set(UART7_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART7_TX_GPIO_PINx); + gpio_af_set(UART7_GPIOx, UART7_GPIO_AFx, UART7_RX_GPIO_PINx); + gpio_mode_set(UART7_GPIOx, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART7_RX_GPIO_PINx); + gpio_output_options_set(UART7_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, UART7_RX_GPIO_PINx); break; #endif default: @@ -259,8 +259,8 @@ void _gpio_init(const uint32_t usart_periph) { #endif void gd32_uart_begin(const uint32_t usart_periph, uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop_bits) { - _rcu_periph_clock_enable(usart_periph); - _gpio_init(usart_periph); + rcu_config(usart_periph); + gpio_config(usart_periph); usart_deinit(usart_periph); @@ -307,7 +307,11 @@ void gd32_uart_transmit(const uint32_t usart_periph, const uint8_t *data, uint32 while (length-- != 0) { while (RESET == usart_flag_get(usart_periph, USART_FLAG_TBE)) ; - USART_DATA(usart_periph) = ((uint16_t) USART_DATA_DATA & *data++); +#if defined (GD32H7XX) + USART_TDATA(usart_periph) = USART_TDATA_TDATA & (uint32_t)*data++; +#else + USART_DATA(usart_periph) = (USART_DATA_DATA & *data++); +#endif } } @@ -318,6 +322,10 @@ void gd32_uart_transmit_string(const uint32_t usart_periph, const char *data) { while (*data != '\0') { while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) ; - USART_DATA(usart_periph) = ((uint16_t) USART_DATA_DATA & *data++); +#if defined (GD32H7XX) + USART_TDATA(usart_periph) = USART_TDATA_TDATA & (uint32_t)*data++; +#else + USART_DATA(usart_periph) = (USART_DATA_DATA & *data++); +#endif } } diff --git a/lib-gd32/src/mac_address.cpp b/lib-gd32/src/mac_address.cpp index fe9b2d4..0306485 100644 --- a/lib-gd32/src/mac_address.cpp +++ b/lib-gd32/src/mac_address.cpp @@ -2,7 +2,7 @@ * @file mac_address.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,12 +29,15 @@ #include "debug.h" void mac_address_get(uint8_t paddr[]) { -#if !defined (GD32F4XX) - const auto mac_hi = *(volatile uint32_t *) (0x1FFFF7E8); - const auto mac_lo = *(volatile uint32_t *) (0x1FFFF7EC); -#else +#if defined (GD32H7XX) + const auto mac_hi = *(volatile uint32_t *) (0x1FF0F7E8); + const auto mac_lo = *(volatile uint32_t *) (0x1FF0F7EC); +#elif defined (GD32F4XX) const auto mac_hi = *(volatile uint32_t *) (0x1FFF7A10); const auto mac_lo = *(volatile uint32_t *) (0x1FFF7A14); +#else + const auto mac_hi = *(volatile uint32_t *) (0x1FFFF7E8); + const auto mac_lo = *(volatile uint32_t *) (0x1FFFF7EC); #endif paddr[0] = 2; diff --git a/lib-gd32/src/ptp/gd32_ptp.cpp b/lib-gd32/src/ptp/gd32_ptp.cpp new file mode 100644 index 0000000..a027d5c --- /dev/null +++ b/lib-gd32/src/ptp/gd32_ptp.cpp @@ -0,0 +1,183 @@ +/** + * @file gd32_ptp.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "gd32_ptp.h" +#include "gd32.h" + +#include "debug.h" + +extern "C" void console_error(const char *); + +#if defined (GD32H7XX) +# define enet_interrupt_disable(x) enet_interrupt_disable(ENETx, x) +# define enet_ptp_feature_enable(x) enet_ptp_feature_enable(ENETx, x) +# define enet_ptp_subsecond_increment_config(x) enet_ptp_subsecond_increment_config(ENETx, x) +# define enet_ptp_timestamp_function_config(x) enet_ptp_timestamp_function_config(ENETx, x) +# define enet_ptp_timestamp_addend_config(x) enet_ptp_timestamp_addend_config(ENETx, x) +# define enet_ptp_timestamp_update_config(x,y,z) enet_ptp_timestamp_update_config(ENETx, x, y, z) +# define enet_ptp_system_time_get(x) enet_ptp_system_time_get(ENETx, x) +static FlagStatus enet_ptpflagstatus_get(const uint32_t flag) { + FlagStatus bitstatus = RESET; + + if (0 != (ENET_PTP_TSCTL(ENETx) & flag)) { + bitstatus = SET; + } + + return bitstatus; +} +#else +static FlagStatus enet_ptpflagstatus_get(const uint32_t flag) { + FlagStatus bitstatus = RESET; + + if (0 != (ENET_PTP_TSCTL & flag)) { + bitstatus = SET; + } + + return bitstatus; +} +#endif + +static void ptp_start(const uint32_t init_sec, const uint32_t init_subsec, [[maybe_unused]] const uint32_t carry_cfg, const uint32_t accuracy_cfg) { + DEBUG_ENTRY + + enet_interrupt_disable(ENET_MAC_INT_TMSTIM); + +#if defined(GD32F4XX) || defined (GD32H7XX) + enet_ptp_feature_enable(ENET_ALL_RX_TIMESTAMP | ENET_RXTX_TIMESTAMP); +#else + enet_ptp_feature_enable(ENET_RXTX_TIMESTAMP); +#endif + enet_ptp_subsecond_increment_config(accuracy_cfg); + + enet_ptp_timestamp_addend_config(carry_cfg); + + enet_ptp_timestamp_function_config(ENET_PTP_ADDEND_UPDATE); + while(enet_ptpflagstatus_get(ENET_PTP_ADDEND_UPDATE) == SET); + + enet_ptp_timestamp_function_config(ENET_PTP_FINEMODE); + + enet_ptp_timestamp_update_config(ENET_PTP_ADD_TO_TIME, init_sec, init_subsec); + enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_INIT); + while(enet_ptpflagstatus_get(ENET_PTP_SYSTIME_INIT) == SET); + + DEBUG_EXIT +} + +void gd32_ptp_start() { + DEBUG_ENTRY + DEBUG_PRINTF("PTP_TICK=%u", gd32::ptp::PTP_TICK); + DEBUG_PRINTF("ADJ_FREQ_BASE_INCREMENT=%u", gd32::ptp::ADJ_FREQ_BASE_INCREMENT); + DEBUG_PRINTF("ADJ_FREQ_BASE_ADDEND=x%X", gd32::ptp::ADJ_FREQ_BASE_ADDEND); + + struct tm tmbuf; + memset(&tmbuf, 0, sizeof(struct tm)); + tmbuf.tm_mday = _TIME_STAMP_DAY_; // The day of the month, in the range 1 to 31. + tmbuf.tm_mon = _TIME_STAMP_MONTH_ - 1; // The number of months since January, in the range 0 to 11. + tmbuf.tm_year = _TIME_STAMP_YEAR_ - 1900; // The number of years since 1900. + + ptp_start(mktime(&tmbuf), 0, gd32::ptp::ADJ_FREQ_BASE_ADDEND, gd32::ptp::ADJ_FREQ_BASE_INCREMENT); + +#ifndef NDEBUG + struct timeval tv; + gettimeofday(&tv, nullptr); + auto *tm = localtime(&tv.tv_sec); + + DEBUG_PRINTF("%.2d-%.2d-%.4d %.2d:%.2d:%.2d.%.6d", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, static_cast(tv.tv_usec)); +#endif + DEBUG_EXIT +} + +void gd32_ptp_get_time(gd32::ptp::ptptime *ptp_time) { + enet_ptp_systime_struct systime; + + enet_ptp_system_time_get(&systime); + + ptp_time->tv_sec = systime.second; +#if !defined (GD32F4XX) + ptp_time->tv_nsec = systime.nanosecond; +#else + ptp_time->tv_nsec = gd32::ptp_subsecond_2_nanosecond(systime.subsecond); +#endif +} + +void gd32_ptp_set_time(const gd32::ptp::ptptime *ptp_time) { + const auto nSign = ENET_PTP_ADD_TO_TIME; + const auto nSecond = ptp_time->tv_sec; + const auto nNanoSecond = ptp_time->tv_nsec; + const auto nSubSecond = gd32::ptp_nanosecond_2_subsecond(nNanoSecond); + + enet_ptp_timestamp_update_config(nSign, nSecond, nSubSecond); + enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_INIT); + while(enet_ptpflagstatus_get(ENET_PTP_SYSTIME_INIT) == SET); +} + +void gd32_ptp_update_time(const gd32::ptp::time_t *pTime) { + uint32_t nSign; + uint32_t nSecond; + uint32_t nNanoSecond; + + if (pTime->tv_sec < 0 || (pTime->tv_sec == 0 && pTime->tv_nsec < 0)) { + nSign = ENET_PTP_SUBSTRACT_FROM_TIME; + nSecond = -pTime->tv_sec; + nNanoSecond = -pTime->tv_nsec; + } else { + nSign = ENET_PTP_ADD_TO_TIME; + nSecond = pTime->tv_sec; + nNanoSecond = pTime->tv_nsec; + } + + const auto nSubSecond = gd32::ptp_nanosecond_2_subsecond(nNanoSecond); +#if defined (GD32H7XX) + const auto nAddend = ENET_PTP_TSADDEND(ENETx); +#else + const auto nAddend = ENET_PTP_TSADDEND; +#endif + + enet_ptp_timestamp_update_config(nSign, nSecond, nSubSecond); + enet_ptp_timestamp_function_config(ENET_PTP_SYSTIME_UPDATE); + while(enet_ptpflagstatus_get(ENET_PTP_SYSTIME_UPDATE) == SET); + + enet_ptp_timestamp_addend_config(nAddend); + enet_ptp_timestamp_function_config(ENET_PTP_ADDEND_UPDATE); +} + +bool gd32_adj_frequency(const int32_t adjust_ppb) { + const uint32_t addend = gd32::ptp::ADJ_FREQ_BASE_ADDEND + static_cast((((static_cast(gd32::ptp::ADJ_FREQ_BASE_ADDEND)) * adjust_ppb) / 1000000000ULL)); + + enet_ptp_timestamp_addend_config(addend); + + const auto reval = enet_ptp_timestamp_function_config(ENET_PTP_ADDEND_UPDATE); + + if (reval == ERROR) { + console_error("enet_ptp_timestamp_addend_config\n"); + } + + return reval != ERROR; +} diff --git a/lib-gd32/src/softuart0/gd32_uart0.c b/lib-gd32/src/softuart0/gd32_uart0.c deleted file mode 100644 index 7f8dee8..0000000 --- a/lib-gd32/src/softuart0/gd32_uart0.c +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @file gd32_uart0.c - * - */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@gd32-dmx.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#if defined (NDEBUG) -# undef NDEBUG -#endif - -#include -#include -#include - -#include "gd32.h" - -#if !defined (SOFTUART_TX_PINx) -# define SOFTUART_TX_PINx GPIO_PIN_9 -# define SOFTUART_TX_GPIOx GPIOA -# define SOFTUART_TX_RCU_GPIOx RCU_GPIOA -#endif - -#if defined (GD32F4XX) -# define TIMER_CLOCK (APB2_CLOCK_FREQ * 2) -#else -# define TIMER_CLOCK (APB2_CLOCK_FREQ) -#endif - -#define BAUD_RATE (115200U) -#define TIMER_PERIOD ((TIMER_CLOCK / BAUD_RATE) - 1U) -#define BUFFER_SIZE (128U) - -typedef enum { - SOFTUART_IDLE, - SOFTUART_START_BIT, - SOFTUART_DATA, - SOFTUART_STOP_BIT, -} softuart_state; - -struct circular_buffer { - uint8_t buffer[BUFFER_SIZE]; - uint32_t head; - uint32_t tail; - bool full; -}; - -static volatile softuart_state s_state; -static volatile struct circular_buffer s_circular_buffer; -static volatile uint8_t s_data; -static volatile uint8_t s_shift; - -static bool is_circular_buffer_empty() { - return (!s_circular_buffer.full && (s_circular_buffer.head == s_circular_buffer.tail)); -} - -void TIMER0_UP_TIMER9_IRQHandler() { - GPIO_BOP(LED3_GPIOx) = LED3_GPIO_PINx; - - switch (s_state) { - case SOFTUART_IDLE: - break; - case SOFTUART_START_BIT: - GPIO_BC(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; - - s_state = SOFTUART_DATA; - s_data = s_circular_buffer.buffer[s_circular_buffer.tail]; - s_circular_buffer.tail = (s_circular_buffer.tail + 1) & (BUFFER_SIZE - 1); - s_circular_buffer.full = false; - s_shift = 0; - break; - case SOFTUART_DATA: - if (s_data & (1U << s_shift)) { - GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; - } else { - GPIO_BC(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; - } - - s_shift++; - - if (s_shift == 8) { - s_state = SOFTUART_STOP_BIT; - } - break; - case SOFTUART_STOP_BIT: - GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; - - if (is_circular_buffer_empty()) { - s_state = SOFTUART_IDLE; - timer_disable(TIMER9); - } else { - s_state = SOFTUART_START_BIT; - } - break; - default: - break; - } - - timer_interrupt_flag_clear(TIMER9, TIMER_INT_FLAG_UP); - - GPIO_BC(LED3_GPIOx) = LED3_GPIO_PINx; -} - -void uart0_init() { - rcu_periph_clock_enable (LED3_RCU_GPIOx); -#if !defined (GD32F4XX) - gpio_init(LED3_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED3_GPIO_PINx); -#else - gpio_mode_set(LED3_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, LED3_GPIO_PINx); - gpio_output_options_set(LED3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED3_GPIO_PINx); - gpio_af_set(LED3_GPIOx, GPIO_AF_0, LED3_GPIO_PINx); -#endif - - GPIO_BC(LED3_GPIOx) = LED3_GPIO_PINx; - - rcu_periph_clock_enable (SOFTUART_TX_RCU_GPIOx); - -#if !defined (GD32F4XX) - gpio_init(SOFTUART_TX_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SOFTUART_TX_PINx); -#else - gpio_mode_set(SOFTUART_TX_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, SOFTUART_TX_PINx); - gpio_output_options_set(SOFTUART_TX_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SOFTUART_TX_PINx); - gpio_af_set(SOFTUART_TX_GPIOx, GPIO_AF_0, SOFTUART_TX_PINx); -#endif - - GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; - - rcu_periph_clock_enable(RCU_TIMER9); - - timer_deinit(TIMER9); - - timer_parameter_struct timer_initpara; - timer_initpara.prescaler = 0; - timer_initpara.alignedmode = TIMER_COUNTER_EDGE; - timer_initpara.counterdirection = TIMER_COUNTER_UP; - timer_initpara.period = TIMER_PERIOD; - timer_initpara.clockdivision = TIMER_CKDIV_DIV1; - - timer_init(TIMER9, &timer_initpara); - - timer_flag_clear(TIMER9, ~0); - timer_interrupt_flag_clear(TIMER9, ~0); - - timer_interrupt_enable(TIMER9, TIMER_INT_UP); - - NVIC_SetPriority(TIMER0_UP_TIMER9_IRQn, 2); - NVIC_EnableIRQ(TIMER0_UP_TIMER9_IRQn); -} - -static void _putc(int c) { - while (s_circular_buffer.full) - ; - - s_circular_buffer.buffer[s_circular_buffer.head] = (uint8_t) c; - s_circular_buffer.head = (s_circular_buffer.head + 1) & (BUFFER_SIZE - 1); - s_circular_buffer.full = s_circular_buffer.head == s_circular_buffer.tail; - - if (s_state == SOFTUART_IDLE) { - timer_counter_value_config(TIMER9, 0); - timer_enable(TIMER9); - s_state = SOFTUART_START_BIT; - } -} - -void uart0_putc(int c) { - if (c == '\n') { - _putc('\r'); - } - - _putc(c); -} diff --git a/lib-gd32/src/softuart0/uart0.cpp b/lib-gd32/src/softuart0/uart0.cpp new file mode 100644 index 0000000..1402773 --- /dev/null +++ b/lib-gd32/src/softuart0/uart0.cpp @@ -0,0 +1,234 @@ +/** + * @file uart0.c + * + */ +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +#endif + +#include +#include + +#include "gd32.h" + +#include "debug.h" + +#if defined (GD32H7XX) +# define TIMERx TIMER15 +# define RCU_TIMERx RCU_TIMER15 +# define TIMERx_IRQHandler TIMER15_IRQHandler +# define TIMERx_IRQn TIMER15_IRQn +#else +# define TIMERx TIMER9 +# define RCU_TIMERx RCU_TIMER9 +# define TIMERx_IRQHandler TIMER0_UP_TIMER9_IRQHandler +# define TIMERx_IRQn TIMER0_UP_TIMER9_IRQn +#endif + +#if defined (GD32H7XX) +# define TIMER_CLOCK_FREQ (AHB_CLOCK_FREQ) +#elif defined (GD32F4XX) +# define TIMER_CLOCK_FREQ (APB2_CLOCK_FREQ * 2) +#else +# define TIMER_CLOCK_FREQ (APB2_CLOCK_FREQ) +#endif + +#if !defined (SOFTUART_TX_PINx) +# define SOFTUART_TX_PINx GPIO_PIN_9 +# define SOFTUART_TX_GPIOx GPIOA +# define SOFTUART_TX_RCU_GPIOx RCU_GPIOA +#endif + +#define BAUD_RATE (115200U) +#define TIMER_PERIOD ((TIMER_CLOCK_FREQ / BAUD_RATE) - 1U) +#define BUFFER_SIZE (128U) + +typedef enum { + SOFTUART_IDLE, SOFTUART_START_BIT, SOFTUART_DATA, SOFTUART_STOP_BIT, +} softuart_state; + +struct circular_buffer { + uint8_t buffer[BUFFER_SIZE]; + uint32_t head; + uint32_t tail; + bool full; +}; + +static volatile softuart_state s_state; +static volatile struct circular_buffer s_circular_buffer; +static volatile uint8_t s_data; +static volatile uint8_t s_shift; + +static bool is_circular_buffer_empty() { + return (!s_circular_buffer.full && (s_circular_buffer.head == s_circular_buffer.tail)); +} + +extern "C" { +void TIMERx_IRQHandler() { + const auto nIntFlag = TIMER_INTF(TIMERx); + + if ((nIntFlag & TIMER_INT_FLAG_UP) == TIMER_INT_FLAG_UP) { +#if defined (LED3_GPIO_PINx) + GPIO_BOP(LED3_GPIOx) = LED3_GPIO_PINx; +#endif + + switch (s_state) { + case SOFTUART_IDLE: + break; + case SOFTUART_START_BIT: + GPIO_BC(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; + + s_state = SOFTUART_DATA; + s_data = s_circular_buffer.buffer[s_circular_buffer.tail]; + s_circular_buffer.tail = (s_circular_buffer.tail + 1) & (BUFFER_SIZE - 1); + s_circular_buffer.full = false; + s_shift = 0; + break; + case SOFTUART_DATA: + if (s_data & (1U << s_shift)) { + GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; + } else { + GPIO_BC(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; + } + + s_shift++; + + if (s_shift == 8) { + s_state = SOFTUART_STOP_BIT; + } + break; + case SOFTUART_STOP_BIT: + GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; + + if (is_circular_buffer_empty()) { + s_state = SOFTUART_IDLE; + timer_disable(TIMERx); + } else { + s_state = SOFTUART_START_BIT; + } + break; + default: + break; + } + +#if defined (LED3_GPIO_PINx) + GPIO_BC(LED3_GPIOx) = LED3_GPIO_PINx; +#endif + } + + TIMER_INTF(TIMERx) = static_cast(~nIntFlag); +} + +void uart0_init() { + s_state = SOFTUART_IDLE; + s_circular_buffer.head = 0; + s_circular_buffer.tail = 0; + s_circular_buffer.full = false; + +#if defined (LED3_GPIO_PINx) + rcu_periph_clock_enable (LED3_RCU_GPIOx); +# if defined (GPIO_INIT) + gpio_init(LED3_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED3_GPIO_PINx); +# else + gpio_mode_set(LED3_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, LED3_GPIO_PINx); + gpio_output_options_set(LED3_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, LED3_GPIO_PINx); +# endif + + GPIO_BC(LED3_GPIOx) = LED3_GPIO_PINx; +#endif + + rcu_periph_clock_enable (SOFTUART_TX_RCU_GPIOx); + +#if defined (GPIO_INIT) + gpio_init(SOFTUART_TX_GPIOx, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SOFTUART_TX_PINx); +#else + gpio_mode_set(SOFTUART_TX_GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, SOFTUART_TX_PINx); + gpio_output_options_set(SOFTUART_TX_GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED, SOFTUART_TX_PINx); +#endif + + GPIO_BOP(SOFTUART_TX_GPIOx) = SOFTUART_TX_PINx; + + rcu_periph_clock_enable(RCU_TIMERx); + + timer_deinit(TIMERx); + + timer_parameter_struct timer_initpara; + timer_struct_para_init(&timer_initpara); + + timer_initpara.prescaler = 0; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = TIMER_PERIOD; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_initpara.repetitioncounter = 0; + + timer_init(TIMERx, &timer_initpara); + + timer_flag_clear(TIMERx, ~0); + timer_interrupt_flag_clear(TIMERx, ~0); + + timer_interrupt_enable(TIMERx, TIMER_INT_UP); + + NVIC_SetPriority(TIMERx_IRQn, 2); + NVIC_EnableIRQ(TIMERx_IRQn); +} + +static void _putc(const int c) { + //FIXME deadlock when timer is not running + while (s_circular_buffer.full) + ; + + s_circular_buffer.buffer[s_circular_buffer.head] = (uint8_t) c; + s_circular_buffer.head = (s_circular_buffer.head + 1) & (BUFFER_SIZE - 1); + s_circular_buffer.full = s_circular_buffer.head == s_circular_buffer.tail; + + if (s_state == SOFTUART_IDLE) { + timer_counter_value_config(TIMERx, 0); + timer_enable(TIMERx); + s_state = SOFTUART_START_BIT; + } +} + +void uart0_putc(int c) { + if (c == '\n') { + _putc('\r'); + } + + _putc(c); +} + +void uart0_puts(const char *s) { + while (*s != '\0') { + if (*s == '\n') { + uart0_putc('\r'); + } + uart0_putc(*s++); + } + + do { + __DMB(); + } while (!is_circular_buffer_empty()); +} +} diff --git a/lib-gd32/src/systick.c b/lib-gd32/src/systick/systick.cpp similarity index 77% rename from lib-gd32/src/systick.c rename to lib-gd32/src/systick/systick.cpp index 2e9e672..f269c58 100644 --- a/lib-gd32/src/systick.c +++ b/lib-gd32/src/systick/systick.cpp @@ -2,7 +2,7 @@ * @file systick.c * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,23 +23,24 @@ * THE SOFTWARE. */ -#include +#include #include "gd32.h" -volatile uint32_t s_nSysTickMillis; +volatile uint32_t gv_nSysTickMillis; -void systick_config(void) { - /* setup systick timer for 1000Hz interrupts */ +extern "C" { +void systick_config() { + /* Setup systick timer for 1000Hz interrupts */ if (SysTick_Config(SystemCoreClock / 1000U)) { - /* capture error */ while (1) { } } - /* configure the systick handler priority */ - NVIC_SetPriority(SysTick_IRQn, 0x00U); + + NVIC_SetPriority(SysTick_IRQn, (1UL<<__NVIC_PRIO_BITS)-1UL); // Lowest priority } -void SysTick_Handler(void) { - s_nSysTickMillis++; +void SysTick_Handler() { + gv_nSysTickMillis++; +} } diff --git a/lib-gd32/src/timer6.cpp b/lib-gd32/src/timer6.cpp new file mode 100644 index 0000000..0cbf908 --- /dev/null +++ b/lib-gd32/src/timer6.cpp @@ -0,0 +1,86 @@ +/** + * @file timer6.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma GCC push_options +#pragma GCC optimize ("O2") + +#include "gd32.h" + +struct HwTimersSeconds g_Seconds; + +extern "C" { +#if defined (CONFIG_TIMER6_HAVE_NO_IRQ_HANDLER) +void TIMER6_IRQHandler() { + const auto nIntFlag = TIMER_INTF(TIMER6); + + if ((nIntFlag & TIMER_INT_FLAG_UP) == TIMER_INT_FLAG_UP) { + g_Seconds.nUptime++; + } + + TIMER_INTF(TIMER6) = static_cast(~nIntFlag); +} +#endif +} + +void timer6_config() { + g_Seconds.nUptime = 0; + + rcu_periph_clock_enable(RCU_TIMER6); + timer_deinit(TIMER6); + + timer_parameter_struct timer_initpara; + timer_struct_para_init(&timer_initpara); + + timer_initpara.prescaler = TIMER_PSC_10KHZ; + timer_initpara.period = (10000 - 1); // 1 second + timer_init(TIMER6, &timer_initpara); + + timer_counter_value_config(TIMER6, 0); + + timer_interrupt_flag_clear(TIMER6, ~0); + + timer_interrupt_enable(TIMER6, TIMER_INT_UP); + + NVIC_SetPriority(TIMER6_IRQn, (1UL<<__NVIC_PRIO_BITS)-1UL); // Lowest priority + NVIC_EnableIRQ(TIMER6_IRQn); + + timer_enable(TIMER6); +} + +uint32_t timer6_get_elapsed_milliseconds() { + const auto nUptimeFirst = g_Seconds.nUptime; + auto nTimerCount = TIMER_CNT(TIMER6); + const auto nUptimeSecond = g_Seconds.nUptime; + + // Check for consistency + if (__builtin_expect((nUptimeFirst == nUptimeSecond), 1)) { + // No overflow detected, return the calculated time + return (nUptimeFirst * 1000U) + (nTimerCount / 10U); + } + + // Potential overflow detected, re-read the timer count + nTimerCount = TIMER_CNT(TIMER6); + return (nUptimeSecond * 1000U) + (nTimerCount / 10U); +} diff --git a/lib-gd32/src/gd32_uart0.c b/lib-gd32/src/uart0.cpp similarity index 81% rename from lib-gd32/src/gd32_uart0.c rename to lib-gd32/src/uart0.cpp index 17335bd..7562f3b 100644 --- a/lib-gd32/src/gd32_uart0.c +++ b/lib-gd32/src/uart0.cpp @@ -1,8 +1,8 @@ /** - * @file gd32_uart0.c + * @file uart0.cpp * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,23 +23,13 @@ * THE SOFTWARE. */ -#include -#include - -extern void uart0_putc(int); +#include +#include static char s_buffer[128]; -void uart0_puts(const char *s) { - while (*s != '\0') { - if (*s == '\n') { - uart0_putc('\r'); - } - uart0_putc(*s++); - } - -// uart0_putc('\n'); //TODO Add '\n' -} +extern "C" { +void uart0_putc(int); int uart0_printf(const char *fmt, ...) { va_list arp; @@ -61,3 +51,4 @@ int uart0_printf(const char *fmt, ...) { return i; } +} diff --git a/lib-gd32/src/uart0/gd32_uart0.c b/lib-gd32/src/uart0/uart0.cpp similarity index 66% rename from lib-gd32/src/uart0/gd32_uart0.c rename to lib-gd32/src/uart0/uart0.cpp index e7c531f..4adcc13 100644 --- a/lib-gd32/src/uart0/gd32_uart0.c +++ b/lib-gd32/src/uart0/uart0.cpp @@ -1,8 +1,8 @@ /** - * @file gd32_uart0.c + * @file uart0.cpp * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,12 +23,13 @@ * THE SOFTWARE. */ -#include -#include +#include +#include #include "gd32.h" #include "gd32_uart.h" +extern "C" { void uart0_init(void) { gd32_uart_begin(USART0, 115200U, GD32_UART_BITS_8, GD32_UART_PARITY_NONE, GD32_UART_STOP_1BIT); } @@ -37,11 +38,46 @@ void uart0_putc(int c) { if (c == '\n') { while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) ; +#if defined (GD32H7XX) + USART_TDATA(USART0) = USART_TDATA_TDATA & (uint32_t)'\r'; +#else USART_DATA(USART0) = ((uint16_t) USART_DATA_DATA & (uint8_t) '\r'); +#endif } while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) ; - +#if defined (GD32H7XX) + USART_TDATA(USART0) = USART_TDATA_TDATA & (uint32_t) c; +#else USART_DATA(USART0) = ((uint16_t) USART_DATA_DATA & (uint8_t) c); +#endif +} + +void uart0_puts(const char *s) { + while (*s != '\0') { + if (*s == '\n') { + uart0_putc('\r'); + } + uart0_putc(*s++); + } +} + +int uart0_getc(void) { + if (__builtin_expect((!gd32_usart_flag_get(USART0)), 1)) { + return EOF; + } + +#if defined (GD32H7XX) + const auto c = static_cast(USART_RDATA(USART0)); +#else + const auto c = static_cast(USART_DATA(USART0)); +#endif + +#if defined (UART0_ECHO) + uart0_putc(c); +#endif + + return c; +} } diff --git a/lib-gd32/src/udelay.cpp b/lib-gd32/src/udelay.cpp index 81cb713..737780d 100644 --- a/lib-gd32/src/udelay.cpp +++ b/lib-gd32/src/udelay.cpp @@ -2,7 +2,7 @@ * @file udelay.cpp * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,9 +28,9 @@ #include "gd32.h" -static constexpr auto TICKS_PER_US = (MCU_CLOCK_FREQ / 1000000U); +static constexpr uint32_t TICKS_PER_US = (MCU_CLOCK_FREQ / 1000000U); -void udelay_init(void) { +void udelay_init() { assert(MCU_CLOCK_FREQ == SystemCoreClock); CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; @@ -38,21 +38,20 @@ void udelay_init(void) { DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; } -void udelay(uint32_t nUs, uint32_t nOffsetCYCCNT) { - const auto nTicks = nUs * TICKS_PER_US; +void udelay(uint32_t nMicros, uint32_t nOffsetMicros) { + const auto nTicks = nMicros * TICKS_PER_US; uint32_t nTicksCount = 0; - uint32_t nTicksNow; uint32_t nTicksPrevious; - if (nOffsetCYCCNT == 0) { + if (nOffsetMicros == 0) { nTicksPrevious = DWT->CYCCNT; } else { - nTicksPrevious = nOffsetCYCCNT; + nTicksPrevious = nOffsetMicros; } while (1) { - nTicksNow = DWT->CYCCNT; + const auto nTicksNow = DWT->CYCCNT; if (nTicksNow != nTicksPrevious) { if (nTicksNow > nTicksPrevious) { diff --git a/lib-hal/.cproject b/lib-hal/.cproject index 70288f4..ed5bbd3 100644 --- a/lib-hal/.cproject +++ b/lib-hal/.cproject @@ -27,7 +27,6 @@
diff --git a/lib-network/.settings/org.eclipse.cdt.core.prefs b/lib-network/.settings/org.eclipse.cdt.core.prefs deleted file mode 100644 index c8ec5df..0000000 --- a/lib-network/.settings/org.eclipse.cdt.core.prefs +++ /dev/null @@ -1,6 +0,0 @@ -doxygen/doxygen_new_line_after_brief=true -doxygen/doxygen_use_brief_tag=false -doxygen/doxygen_use_javadoc_tags=true -doxygen/doxygen_use_pre_tag=false -doxygen/doxygen_use_structural_commands=false -eclipse.preferences.version=1 diff --git a/lib-network/Makefile.GD32 b/lib-network/Makefile.GD32 index 2828c4a..161f1c6 100644 --- a/lib-network/Makefile.GD32 +++ b/lib-network/Makefile.GD32 @@ -1,17 +1,41 @@ -DEFINES =DISABLE_FS +$(info "lib-network/Makefile.GD32") + +DEFINES =DISABLE_FS DEFINES+=NDEBUG -EXTRA_INCLUDES=../lib-properties/include +EXTRA_INCLUDES=../lib-properties/include ../lib-display/include EXTRA_SRCDIR=src/emac/gd32 -$(info $$PHY_TYPE [${PHY_TYPE}]) - -ifeq ($(findstring RTL8201F,$(PHY_TYPE)), RTL8201F) - EXTRA_SRCDIR+=src/emac/gd32/rtl8201f - DEFINES+=RTL8201F_LED1_LINK_ALL - DEFINES+=ENET_LINK_CHECK_USE_INT +ifneq ($(MAKE_FLAGS),) + ifeq ($(findstring gd32f10x,$(FAMILY)), gd32f10x) + EXTRA_SRCDIR+=src/emac/gd32/f + endif + ifeq ($(findstring gd32f20x,$(FAMILY)), gd32f20x) + EXTRA_SRCDIR+=src/emac/gd32/f + endif + ifeq ($(findstring gd32f4xx,$(FAMILY)), gd32f4xx) + EXTRA_SRCDIR+=src/emac/gd32/f + endif + ifeq ($(findstring gd32h7xx,$(FAMILY)), gd32h7xx) + EXTRA_SRCDIR+=src/emac/gd32/h + endif + + ifeq ($(findstring RTL8201F,$(MAKE_FLAGS)), RTL8201F) + EXTRA_SRCDIR+=src/emac/gd32/rtl8201f + endif + + ifeq ($(findstring ENABLE_PHY_SWITCH,$(MAKE_FLAGS)), ENABLE_PHY_SWITCH) + EXTRA_SRCDIR+=src/emac/gd32/dsa/88e6161 + endif + + ifeq ($(findstring CONFIG_ENET_ENABLE_PTP,$(MAKE_FLAGS)), CONFIG_ENET_ENABLE_PTP) + ifeq ($(findstring ENABLE_NTP_PTP_CLIENT,$(MAKE_FLAGS)), ENABLE_NTP_PTP_CLIENT) + EXTRA_SRCDIR+=src/net/apps/ntp/gd32/ptp + endif + endif else - DEFINES+=ENET_LINK_CHECK_REG_POLL + EXTRA_SRCDIR+=src/emac/gd32/f + ENET_PHY=RTL8201F endif include Rules.mk diff --git a/lib-network/Rules.mk b/lib-network/Rules.mk old mode 100755 new mode 100644 index 069b63b..15e929d --- a/lib-network/Rules.mk +++ b/lib-network/Rules.mk @@ -15,9 +15,9 @@ ifneq ($(MAKE_FLAGS),) endif endif ifndef COND - EXTRA_SRCDIR+=src/apps/mdns src/apps/ntp src/apps/tftp - EXTRA_SRCDIR+=src/emac src/params src/net - EXTRA_SRCDIR+=src/emac/phy + EXTRA_SRCDIR+=src/net/apps/mdns src/net/apps/ntp src/net/apps/tftp + EXTRA_SRCDIR+=src/emac src/net src/emac/phy + EXTRA_SRCDIR+=src/params ifeq ($(findstring ENABLE_PHY_SWITCH,$(MAKE_FLAGS)), ENABLE_PHY_SWITCH) EXTRA_SRCDIR+=src/emac/dsa endif @@ -39,9 +39,10 @@ ifneq ($(MAKE_FLAGS),) endif endif else - EXTRA_SRCDIR+=src/apps/mdns src/apps/ntp src/apps/tftp + EXTRA_SRCDIR+=src/net/apps/mdns src/net/apps/ntp src/net/apps/tftp EXTRA_SRCDIR+=src/emac src/net EXTRA_SRCDIR+=src/emac/phy EXTRA_SRCDIR+=src/emac/phy/dp83848 src/emac/phy/lan8700 src/emac/phy/phygen src/emac/phy/rtl8201f + EXTRA_SRCDIR+=src/params DEFINES+=RTL8201F_LED1_LINK_ALL endif diff --git a/lib-network/config/apps_config.h b/lib-network/config/apps_config.h index d2bc3a3..3e82f26 100644 --- a/lib-network/config/apps_config.h +++ b/lib-network/config/apps_config.h @@ -2,7 +2,7 @@ * @file apps_config * */ -/* Copyright (C) 2021-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,9 @@ #ifndef APPS_CONFIG_H_ #define APPS_CONFIG_H_ -#if defined (BARE_METAL) +#if defined(__linux__) || defined (__APPLE__) +# define MDNS_SERVICE_RECORDS_MAX 8 +#else # if defined (H3) # define MDNS_SERVICE_RECORDS_MAX 8 # elif defined (GD32) @@ -36,8 +38,6 @@ # else # error # endif -#else -# define MDNS_SERVICE_RECORDS_MAX 8 #endif #if !defined (MDNS_SERVICE_RECORDS_MAX) diff --git a/lib-network/config/net_config.h b/lib-network/config/net_config.h index fcf1571..96ce794 100644 --- a/lib-network/config/net_config.h +++ b/lib-network/config/net_config.h @@ -2,7 +2,7 @@ * @file net_config * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,26 +26,40 @@ #ifndef NET_CONFIG_H_ #define NET_CONFIG_H_ -#if defined (BARE_METAL) -# define TCP_MAX_PORTS_ALLOWED 1 +#if defined(__linux__) || defined (__APPLE__) +# define UDP_MAX_PORTS_ALLOWED 16 +# define IGMP_MAX_JOINS_ALLOWED (4 + (8 * 4)) /* 8 outputs x 4 Universes */ +# define TCP_MAX_TCBS_ALLOWED 16 +# define TCP_MAX_PORTS_ALLOWED 2 +#else +# define TCP_MAX_PORTS_ALLOWED 1 # if defined (H3) -# define HOST_NAME_PREFIX "allwinner_" +# if !defined(HOST_NAME_PREFIX) +# define HOST_NAME_PREFIX "allwinner_" +# endif # define UDP_MAX_PORTS_ALLOWED 16 # define IGMP_MAX_JOINS_ALLOWED (4 + (8 * 4)) /* 8 outputs x 4 Universes */ +# define TCP_MAX_TCBS_ALLOWED 16 # elif defined (GD32) +/* + * Supports checking IPv4 header checksum and TCP, UDP, or ICMP checksum encapsulated in IPv4 or IPv6 datagram. + */ # define CHECKSUM_BY_HARDWARE -# define HOST_NAME_PREFIX "gigadevice_" +# if !defined(HOST_NAME_PREFIX) +# define HOST_NAME_PREFIX "gigadevice_" +# endif # if !defined (UDP_MAX_PORTS_ALLOWED) -# define UDP_MAX_PORTS_ALLOWED 2 +# define UDP_MAX_PORTS_ALLOWED 8 # endif # if !defined (IGMP_MAX_JOINS_ALLOWED) -# define IGMP_MAX_JOINS_ALLOWED 1 +# define IGMP_MAX_JOINS_ALLOWED (4 + (8 * 4)) /* 8 outputs x 4 Universes */ +# endif +# if !defined (TCP_MAX_TCBS_ALLOWED) +# define TCP_MAX_TCBS_ALLOWED 6 # endif # else # error # endif -#else -# error #endif #if !defined (UDP_MAX_PORTS_ALLOWED) @@ -60,4 +74,8 @@ # error #endif +#if !defined (TCP_MAX_TCBS_ALLOWED) +# error +#endif + #endif /* NET_CONFIG_H_ */ diff --git a/lib-network/include/emac/emac.h b/lib-network/include/emac/emac.h index dbb8597..61eb20e 100755 --- a/lib-network/include/emac/emac.h +++ b/lib-network/include/emac/emac.h @@ -1,5 +1,26 @@ -/* - * emac.h +/** + * @file emac.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ #ifndef EMAC_EMAC_H_ diff --git a/lib-network/include/emac/network.h b/lib-network/include/emac/network.h index 0e946b2..ffd368a 100755 --- a/lib-network/include/emac/network.h +++ b/lib-network/include/emac/network.h @@ -2,7 +2,7 @@ * @file network.h * */ -/* Copyright (C) 2017-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,17 @@ # error This file should not be included #endif +#if !defined (HAVE_NET_HANDLE) +# define HAVE_NET_HANDLE +#endif + +namespace net { +void dhcp_run(); +#if defined (CONFIG_ENET_ENABLE_PTP) +void ptp_run(); +#endif +} // namespace net + #include #include #include @@ -37,7 +48,10 @@ #include "networkparams.h" -#include "../src/net/net.h" +#include "net.h" +#include "netif.h" +#include "ip4_address.h" +#include "net/dhcp.h" #include "emac/net_link_check.h" @@ -45,42 +59,36 @@ class Network { public: - Network(NetworkParamsStore *pNetworkParamsStore); - ~Network() {} + Network(); + ~Network() = default; void Print(); - void Shutdown() { - network::display_emac_shutdown(); - network::mdns_shutdown(); - net_shutdown(); - } - void MacAddressCopyTo(uint8_t *pMacAddress) { - memcpy(pMacAddress, m_aNetMacaddr, network::MAC_SIZE); + memcpy(pMacAddress, net::netif_hwaddr(), NETIF_MAX_HWADDR_LEN); } - uint32_t GetSecondaryIp() const { - return m_IpInfo.secondary_ip.addr; + uint32_t GetSecondaryIp() { + return net::netif_secondary_ipaddr(); } void SetIp(uint32_t nIp); - uint32_t GetIp() const { - return m_IpInfo.ip.addr; + uint32_t GetIp() { + return net::netif_ipaddr(); } void SetNetmask(uint32_t nNetmask); - uint32_t GetNetmask() const { - return m_IpInfo.netmask.addr; + uint32_t GetNetmask() { + return net::netif_netmask(); } void SetGatewayIp(uint32_t nGatewayIp); - uint32_t GetGatewayIp() const { - return m_IpInfo.gw.addr; + uint32_t GetGatewayIp() { + return net::netif_gw(); } - uint32_t GetBroadcastIp() const { - return m_IpInfo.broadcast_ip.addr; + uint32_t GetBroadcastIp() { + return net::netif_broadcast_ipaddr(); } /* @@ -91,18 +99,19 @@ class Network { return m_IsDhcpCapable; } - bool EnableDhcp(); + void EnableDhcp(); - bool IsDhcpUsed() const { - return m_IsDhcpUsed; + bool IsDhcpUsed() { + const auto b = net::netif_dhcp(); + return b; } bool IsDhcpKnown() const { return true; } - network::dhcp::Mode GetDhcpMode() const { - if (m_IsDhcpUsed) { + network::dhcp::Mode GetDhcpMode() { + if (IsDhcpUsed()) { return network::dhcp::Mode::ACTIVE; } @@ -110,22 +119,31 @@ class Network { } /* - * Zeroconf + * Zeroconf / autoip */ + void SetZeroconf(); + bool IsZeroconfUsed() const { + return net::netif_autoip(); + } + bool IsZeroconfCapable() const { return m_IsZeroconfCapable; } - bool SetZeroconf(); - bool IsZeroconfUsed() const { - return m_IsZeroconfUsed; - } + + /* + * Host name + */ void SetHostName(const char *pHostName); const char *GetHostName() const { return m_aHostName; } + /* + * Domain name + */ + void SetDomainName(const char *pDomainName) { strncpy(m_aDomainName, pDomainName, network::DOMAINNAME_SIZE - 1); m_aDomainName[network::DOMAINNAME_SIZE - 1] = '\0'; @@ -134,32 +152,62 @@ class Network { return m_aDomainName; } + /* + * Name servers + */ + + uint32_t GetNameServer(const uint32_t nIndex) const { + if (nIndex < network::NAMESERVERS_COUNT) { + return m_nNameservers[nIndex]; + } + + return 0; + } + + uint32_t GetNameServers() const { + return network::NAMESERVERS_COUNT; + } + + const char *GetIfName() const { + return m_aIfName; + } + + uint32_t GetIfIndex() const { + return 1; + } + /* * UDP/IP */ int32_t Begin(uint16_t nPort) { - const auto nIndex = udp_begin(nPort); + const auto nIndex = net::udp_begin(nPort); assert(nIndex != -1); return nIndex; } int32_t End(uint16_t nPort) { - const auto nIndex = udp_end(nPort); + const auto nIndex = net::udp_end(nPort); assert(nIndex == 0); return nIndex; } - uint16_t RecvFrom(int32_t nHandle, void *pBuffer, uint16_t nLength, uint32_t *from_ip, uint16_t *from_port) { - return udp_recv1(nHandle, reinterpret_cast(pBuffer), nLength, from_ip, from_port); + uint32_t RecvFrom(int32_t nHandle, void *pBuffer, uint32_t nLength, uint32_t *from_ip, uint16_t *from_port) { + return net::udp_recv1(nHandle, reinterpret_cast(pBuffer), nLength, from_ip, from_port); } - uint16_t RecvFrom(int32_t nHandle, const void **ppBuffer, uint32_t *pFromIp, uint16_t *pFromPort) { - return udp_recv2(nHandle, reinterpret_cast(ppBuffer), pFromIp, pFromPort); + uint32_t RecvFrom(int32_t nHandle, const void **ppBuffer, uint32_t *pFromIp, uint16_t *pFromPort) { + return net::udp_recv2(nHandle, reinterpret_cast(ppBuffer), pFromIp, pFromPort); } - void SendTo(int32_t nHandle, const void *pBuffer, uint16_t nLength, uint32_t to_ip, uint16_t remote_port) { - udp_send(nHandle, reinterpret_cast(pBuffer), nLength, to_ip, remote_port); + void SendTo(int32_t nHandle, const void *pBuffer, uint32_t nLength, uint32_t to_ip, uint16_t remote_port) { + if (__builtin_expect((GetIp() != 0), 1)) { + net::udp_send(nHandle, reinterpret_cast(pBuffer), nLength, to_ip, remote_port); + } + } + + void SendToTimestamp(int32_t nHandle, const void *pBuffer, uint32_t nLength, uint32_t to_ip, uint16_t remote_port) { + net::udp_send_timestamp(nHandle, reinterpret_cast(pBuffer), nLength, to_ip, remote_port); } /* @@ -167,33 +215,35 @@ class Network { */ int32_t TcpBegin(const uint16_t nLocalPort) { - return tcp_begin(nLocalPort); + return net::tcp_begin(nLocalPort); } int32_t TcpEnd(const int32_t nHandle); uint16_t TcpRead(const int32_t nHandleListen, const uint8_t **ppBuffer, uint32_t &HandleConnection) { - return tcp_read(nHandleListen, ppBuffer, HandleConnection); + return net::tcp_read(nHandleListen, ppBuffer, HandleConnection); } - void TcpWrite(const int32_t nHandleListen, const uint8_t *pBuffer, uint16_t nLength, const uint32_t HandleConnection) { - tcp_write(nHandleListen, pBuffer, nLength, HandleConnection); + void TcpWrite(const int32_t nHandleListen, const uint8_t *pBuffer, uint32_t nLength, const uint32_t HandleConnection) { + net::tcp_write(nHandleListen, pBuffer, nLength, HandleConnection); } /* * IGMP */ - void JoinGroup(__attribute__((unused)) int32_t nHandle, uint32_t nIp) { - igmp_join(nIp); + void JoinGroup([[maybe_unused]] int32_t nHandle, uint32_t nIp) { + net::igmp_join(nIp); } - void LeaveGroup(__attribute__((unused)) int32_t nHandle, uint32_t nIp) { - igmp_leave(nIp); + void LeaveGroup([[maybe_unused]] int32_t nHandle, uint32_t nIp) { + net::igmp_leave(nIp); } - void SetQueuedStaticIp(uint32_t nLocalIp = 0, uint32_t nNetmask = 0); - void SetQueuedDhcp() { + void SetQueuedStaticIp(const uint32_t nStaticIp, const uint32_t nNetmask); + void SetQueuedDefaultRoute(const uint32_t nGatewayIp); + void SetQueuedDhcp(const network::dhcp::Mode mode) { + m_QueuedConfig.mode = mode; m_QueuedConfig.nMask |= QueuedConfig::DHCP; } void SetQueuedZeroconf() { @@ -202,15 +252,15 @@ class Network { bool ApplyQueuedConfig(); - uint32_t GetNetmaskCIDR() const { - return static_cast(__builtin_popcount(m_IpInfo.netmask.addr)); + uint32_t GetNetmaskCIDR() { + return static_cast(__builtin_popcount(GetNetmask())); } char GetAddressingMode() { - if (Network::Get()->IsZeroconfUsed()) { + if (IsZeroconfUsed()) { return 'Z'; - } else if (Network::Get()->IsDhcpKnown()) { - if (Network::Get()->IsDhcpUsed()) { + } else if (IsDhcpKnown()) { + if (IsDhcpUsed()) { return 'D'; } else { return 'S'; @@ -220,28 +270,15 @@ class Network { return 'U'; } - const char *GetIfName() const { - return m_aIfName; - } - - uint32_t GetIfIndex() const { - return m_nIfIndex; - } - - uint32_t GetNtpServerIp() const { - return m_nNtpServerIp; - } - - float GetNtpUtcOffset() const { - return m_fNtpUtcOffset; - } - - bool IsValidIp(uint32_t nIp) { - return (m_IpInfo.ip.addr & m_IpInfo.netmask.addr) == (nIp & m_IpInfo.netmask.addr); + bool IsValidIp(const uint32_t nIp) { + return (GetIp() & GetNetmask()) == (nIp & GetNetmask()); } void Run() { - net_handle(); + net::net_handle(); +#if defined (CONFIG_ENET_ENABLE_PTP) + net::ptp_run(); +#endif #if defined (ENET_LINK_CHECK_USE_PIN_POLL) net::link_pin_poll(); #elif defined (ENET_LINK_CHECK_REG_POLL) @@ -252,6 +289,7 @@ class Network { net::link_handle_change(link_state); } #endif + net::dhcp_run(); } static Network *Get() { @@ -261,31 +299,25 @@ class Network { private: net::Link s_lastState { net::Link::STATE_DOWN }; bool m_IsDhcpCapable { true }; - bool m_IsDhcpUsed { false }; bool m_IsZeroconfCapable { true }; - bool m_IsZeroconfUsed { false }; - uint32_t m_nIfIndex { 1 }; - uint32_t m_nNtpServerIp { 0 }; - float m_fNtpUtcOffset { 0 }; - - struct IpInfo m_IpInfo; + char m_aIfName[IFNAMSIZ]; char m_aHostName[network::HOSTNAME_SIZE]; char m_aDomainName[network::DOMAINNAME_SIZE]; - uint8_t m_aNetMacaddr[network::MAC_SIZE]; - char m_aIfName[IFNAMSIZ]; - - NetworkStore *m_pNetworkStore { nullptr }; + uint32_t m_nNameservers[network::NAMESERVERS_COUNT]; struct QueuedConfig { static constexpr uint32_t NONE = 0; static constexpr uint32_t STATIC_IP = (1U << 0); - static constexpr uint32_t NET_MASK = (1U << 1); - static constexpr uint32_t DHCP = (1U << 2); - static constexpr uint32_t ZEROCONF = (1U << 3); + static constexpr uint32_t NETMASK = (1U << 1); + static constexpr uint32_t GW = (1U << 2); + static constexpr uint32_t DHCP = (1U << 3); + static constexpr uint32_t ZEROCONF = (1U << 4); uint32_t nMask = QueuedConfig::NONE; - uint32_t nLocalIp = 0; - uint32_t nNetmask = 0; + uint32_t nStaticIp; + uint32_t nNetmask; + uint32_t nGateway; + network::dhcp::Mode mode; }; QueuedConfig m_QueuedConfig; diff --git a/lib-network/include/emac/phy.h b/lib-network/include/emac/phy.h index ddae083..63a8351 100755 --- a/lib-network/include/emac/phy.h +++ b/lib-network/include/emac/phy.h @@ -2,7 +2,7 @@ * @file phy.h * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,7 @@ namespace net { enum class Link { - STATE_UP, STATE_DOWN + STATE_DOWN, STATE_UP }; enum class Duplex { @@ -59,6 +59,7 @@ struct PhyIdentifier { */ bool phy_get_id(const uint32_t nAddress, PhyIdentifier& phyIdentifier); +Link phy_get_link(const uint32_t nAddress); /** * diff --git a/lib-configstore/src/storeremoteconfig.cpp b/lib-network/include/emac/phy/rtl8201f.h similarity index 72% rename from lib-configstore/src/storeremoteconfig.cpp rename to lib-network/include/emac/phy/rtl8201f.h index 8c36dec..eaef1a2 100755 --- a/lib-configstore/src/storeremoteconfig.cpp +++ b/lib-network/include/emac/phy/rtl8201f.h @@ -1,8 +1,8 @@ /** - * @file storeremoteconfig.cpp + * @file rtl8201f.h * */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,20 +23,15 @@ * THE SOFTWARE. */ -#include +#ifndef EMAC_PHY_RTL8201F_H_ +#define EMAC_PHY_RTL8201F_H_ -#include "storeremoteconfig.h" +#include -#include "debug.h" +namespace net::phy { +void rtl8201f_set_rxtiming(const uint32_t nRxTiming); +void rtl8201f_set_txtiming(const uint32_t nTxTiming); +void rtl8201f_get_timings(uint32_t& nRxTiming, uint32_t& nTxTiming); +} // namespace net::phy -StoreRemoteConfig *StoreRemoteConfig::s_pThis = nullptr; - -StoreRemoteConfig::StoreRemoteConfig() { - DEBUG_ENTRY - - assert(s_pThis == nullptr); - s_pThis = this; - - DEBUG_PRINTF("%p", reinterpret_cast(s_pThis)); - DEBUG_EXIT -} +#endif /* EMAC_PHY_RTL8201F_H_ */ diff --git a/lib-network/include/ip4_address.h b/lib-network/include/ip4_address.h new file mode 100755 index 0000000..1ba355b --- /dev/null +++ b/lib-network/include/ip4_address.h @@ -0,0 +1,79 @@ +/* + * ip4_address.h + */ + +#ifndef IP4_ADDRESS_H_ +#define IP4_ADDRESS_H_ + +#include + +#define IP2STR(addr) static_cast(addr & 0xFF), static_cast((addr >> 8) & 0xFF), static_cast((addr >> 16) & 0xFF), static_cast((addr >> 24) & 0xFF) +#define IPSTR "%d.%d.%d.%d" + +#define MAC2STR(mac) static_cast(mac[0]),static_cast(mac[1]),static_cast(mac[2]),static_cast(mac[3]), static_cast(mac[4]), static_cast(mac[5]) +#define MACSTR "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" + +namespace network { +static constexpr uint32_t STORE = 96; ///< Configuration store in bytes +static constexpr uint32_t MAC_SIZE = 6; +static constexpr uint32_t HOSTNAME_SIZE = 64; ///< Including a terminating null byte. +static constexpr uint32_t DOMAINNAME_SIZE = 64; ///< Including a terminating null byte. +static constexpr uint32_t NAMESERVERS_COUNT = 3; +static constexpr uint32_t IP4_ANY = 0x00000000; +static constexpr uint32_t IP4_BROADCAST = 0xffffffff; + +static constexpr uint32_t convert_to_uint(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) { + return static_cast(a) | + static_cast(b) << 8 | + static_cast(c) << 16 | + static_cast(d) << 24; +} + +inline bool is_netmask_valid(uint32_t nNetMask) { + if (nNetMask == 0) { + return false; + } + nNetMask = __builtin_bswap32(nNetMask); + return !(nNetMask & (~nNetMask >> 1)); + +} +/** + * The private address ranges are defined in RFC1918. + */ +inline bool is_private_ip(const uint32_t nIp) { + const uint8_t n = (nIp >> 8) & 0xFF; + + switch (nIp & 0xFF) { + case 10: + return true; + break; + case 172: + return (n >= 16) && (n < 32); + case 192: + return n == 168; + default: + break; + } + + return false; +} + +inline bool is_linklocal_ip(const uint32_t nIp) { + return (nIp & 0xFFFF) == 0xA9FE; +} + +inline bool is_multicast_ip(const uint32_t nIp) { + return (nIp & 0xF0) == 0xE0; +} + +inline uint32_t cidr_to_netmask(const uint8_t nCIDR) { + if (nCIDR != 0) { + const auto nNetmask = __builtin_bswap32(static_cast(~0x0) << (32 - nCIDR)); + return nNetmask; + } + + return 0; +} +} // namespace network + +#endif /* IP4_ADDRESS_H_ */ diff --git a/lib-network/include/mdns.h b/lib-network/include/mdns.h deleted file mode 100644 index ba895f5..0000000 --- a/lib-network/include/mdns.h +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file mdns.h - * - */ -/* Copyright (C) 2019-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MDNS_H_ -#define MDNS_H_ - -#include - -#include "network.h" - -#include "../config/apps_config.h" - -namespace mdns { -struct Flags { - uint32_t qr; - uint32_t opcode; - uint32_t aa; - uint32_t tc; - uint32_t rd; - uint32_t ra; - uint32_t zero; - uint32_t ad; - uint32_t cd; - uint32_t rcode; -}; - -enum class Protocol : uint8_t { - UDP, TCP -}; - -struct ServiceRecord { - char *pName; - char *pServName; - char *pTextContent; - uint16_t nPort; - Protocol nProtocol; -}; - -struct RecordData { - uint32_t nSize; - uint8_t aBuffer[512]; -}; - -static constexpr uint16_t UDP_PORT = 5353; -#if !defined (MDNS_SERVICE_RECORDS_MAX) -static constexpr auto SERVICE_RECORDS_MAX = 8; -#else -static constexpr auto SERVICE_RECORDS_MAX = MDNS_SERVICE_RECORDS_MAX; -#endif -} // namespace mdns - -class MDNS { -public: - MDNS(); - ~MDNS(); - - void Start(); - void Stop() { - Network::Get()->End(mdns::UDP_PORT); - s_nHandle = -1; - } - - void Run(); - - void Print(); - - void SetName(const char *pName); - - bool AddServiceRecord(const char* pName, const char *pServName, uint16_t nPort, mdns::Protocol nProtocol = mdns::Protocol::UDP, const char* pTextContent = nullptr); - -private: - void Parse(); - void HandleRequest(uint16_t nQuestions); - - uint32_t DecodeDNSNameNotation(const char *pDNSNameNotation, char *pString); - - uint32_t WriteDnsName(const char *pSource, char *pDestination, bool bNullTerminated = true); - const char *FindFirstDotFromRight(const char *pString) const; - - void CreateAnswerLocalIpAddress(); - - uint32_t CreateAnswerServiceSrv(uint32_t nIndex, uint8_t *pDestination); - uint32_t CreateAnswerServiceTxt(uint32_t nIndex, uint8_t *pDestination); - uint32_t CreateAnswerServicePtr(uint32_t nIndex, uint8_t *pDestination); - uint32_t CreateAnswerServiceDnsSd(uint32_t nIndex, uint8_t *pDestination); - - void CreateMDNSMessage(uint32_t nIndex); - -#ifndef NDEBUG - void Dump(const struct TmDNSHeader *pmDNSHeader, uint16_t nFlags); -#endif - -private: - static uint32_t s_nMulticastIp; - static int32_t s_nHandle; - static uint32_t s_nRemoteIp; - static uint16_t s_nRemotePort; - static uint16_t s_nBytesReceived; - static uint32_t s_nLastAnnounceMillis; - static uint32_t s_nDNSServiceRecords; - - static mdns::ServiceRecord s_ServiceRecords[mdns::SERVICE_RECORDS_MAX]; - static mdns::RecordData s_AnswerLocalIp; - static mdns::RecordData s_ServiceRecordsData; - - static char *s_pName; - static uint8_t *s_pBuffer; -}; - -#endif /* MDNS_H_ */ diff --git a/lib-network/src/net/net.h b/lib-network/include/net.h old mode 100644 new mode 100755 similarity index 51% rename from lib-network/src/net/net.h rename to lib-network/include/net.h index 47a2786..a60df00 --- a/lib-network/src/net/net.h +++ b/lib-network/include/net.h @@ -2,7 +2,7 @@ * @file net.h * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,46 +28,63 @@ #include -struct ip_addr { - uint32_t addr; -}; +#include "netif.h" +#include "emac/phy.h" +#include "net/dhcp.h" +#include "net/protocol/dhcp.h" -typedef struct ip_addr ip_addr_t; +#include "debug.h" -struct IpInfo { - struct ip_addr ip; - struct ip_addr netmask; - struct ip_addr gw; - struct ip_addr broadcast_ip; - struct ip_addr secondary_ip; -}; +namespace network { +void mdns_shutdown(); +} // namespace network -#define IP_BROADCAST (0xFFFFFFFF) -#define HOST_NAME_MAX 64 /* including a terminating null byte. */ +namespace net { +void tcp_shutdown(); +void igmp_shutdown(); +} -void net_init(const uint8_t *const, struct IpInfo *, const char *, bool *, bool *); -void net_shutdown(); +namespace net { +void net_init(net::Link link, ip4_addr_t ipaddr, ip4_addr_t netmask, ip4_addr_t gw, bool &bUseDhcp); +void net_set_primary_ip(const ip4_addr_t ipaddr); +void net_set_secondary_ip(); void net_handle(); -void net_set_ip(struct IpInfo *); -void net_set_netmask(struct IpInfo *); -void net_set_gw(struct IpInfo *); -bool net_set_zeroconf(struct IpInfo *); - -bool net_set_dhcp(struct IpInfo *, const char *const, bool *); -void net_dhcp_release(); +inline void net_link_down() { + network::mdns_shutdown(); +#if defined (ENABLE_HTTPD) + tcp_shutdown(); +#endif + igmp_shutdown(); + dhcp_release_and_stop(); +} int udp_begin(uint16_t); int udp_end(uint16_t); -uint16_t udp_recv1(int, uint8_t *, uint16_t, uint32_t *, uint16_t *); -uint16_t udp_recv2(int, const uint8_t **, uint32_t *, uint16_t *); -int udp_send(int, const uint8_t *, uint16_t, uint32_t, uint16_t); +uint32_t udp_recv1(int, uint8_t *, uint32_t, uint32_t *, uint16_t *); +uint32_t udp_recv2(int, const uint8_t **, uint32_t *, uint16_t *); +void udp_send(int, const uint8_t *, uint32_t, uint32_t, uint16_t); +void udp_send_timestamp(int, const uint8_t *, uint32_t, uint32_t, uint16_t); void igmp_join(uint32_t); void igmp_leave(uint32_t); int tcp_begin(const uint16_t); uint16_t tcp_read(const int32_t, const uint8_t **, uint32_t &); -void tcp_write(const int32_t, const uint8_t *, uint16_t, const uint32_t); +void tcp_write(const int32_t, const uint8_t *, uint32_t, const uint32_t); + +/** + * Must be provided by the application + */ +void display_emac_config(); +void display_emac_start(); +void display_emac_status(const bool); +void display_emac_shutdown(); +void display_ip(); +void display_netmask(); +void display_gateway(); +void display_hostname(); +void display_dhcp_status(net::dhcp::State); +} // namespace het #endif /* NET_H_ */ diff --git a/lib-configstore/include/storemotors.h b/lib-network/include/net/acd.h similarity index 50% rename from lib-configstore/include/storemotors.h rename to lib-network/include/net/acd.h index 8760c72..f4a8d4f 100755 --- a/lib-configstore/include/storemotors.h +++ b/lib-network/include/net/acd.h @@ -1,8 +1,8 @@ /** - * @file storemotors.h + * @file acd.h * */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,38 +22,50 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +/* This code is inspired by: lwIP + * https://savannah.nongnu.org/projects/lwip/ + */ -#ifndef STOREMOTORS_H_ -#define STOREMOTORS_H_ +#ifndef NET_ACD_H_ +#define NET_ACD_H_ #include -#include "modeparams.h" -#include "motorparams.h" -#include "l6470params.h" -#include "modestore.h" +#include "netif.h" +#include "arp.h" +#include "net/protocol/acd.h" +#include "ip4_address.h" -class StoreMotors final: public ModeParamsStore, public MotorParamsStore, public L6470ParamsStore, public ModeStore { -public: - StoreMotors(); +/** + * https://datatracker.ietf.org/doc/html/rfc5227.html + * IPv4 Address Conflict Detection + */ - void Update(uint32_t nMotorIndex, const struct TModeParams *ptModeParams) override; - void Copy(uint32_t nMotorIndex, struct TModeParams *ptModeParams) override; +namespace net { +typedef void (*acd_conflict_callback_t)(acd::Callback callback); - void Update(uint32_t nMotorIndex, const struct TMotorParams *ptMotorParams) override ; - void Copy(uint32_t nMotorIndex, struct TMotorParams *ptMotorParams) override; +namespace acd { +struct Acd { + ip4_addr_t ipaddr; + State state; + uint8_t sent_num; + uint8_t lastconflict; + uint8_t num_conflicts; + acd_conflict_callback_t acd_conflict_callback; + uint16_t ttw; +}; +} // namespace acd - void Update(uint32_t nMotorIndex, const struct TL6470Params *ptL6470Params) override; - void Copy(uint32_t nMotorIndex, struct TL6470Params *ptL6470Params) override; +void acd_add(struct acd::Acd *, acd_conflict_callback_t); +void acd_remove(struct acd::Acd *); - void SaveDmxStartAddress(uint32_t nMotorIndex, uint16_t nDmxStartAddress) override; +void acd_start(struct acd::Acd *, const ip4_addr_t ipaddr); +void acd_stop(struct acd::Acd *); - static StoreMotors *Get() { - return s_pThis; - } +void acd_arp_reply(struct t_arp *); -private: - static StoreMotors *s_pThis; -}; +void acd_network_changed_link_down(); +void acd_netif_ip_addr_changed(const ip4_addr_t nOldIpAddress, const ip4_addr_t nNewIpAddress); +} // namespace net -#endif /* STOREMOTORS_H_ */ +#endif /* NET_ACD_H_ */ diff --git a/lib-network/include/net/apps/mdns.h b/lib-network/include/net/apps/mdns.h new file mode 100755 index 0000000..4cf05e6 --- /dev/null +++ b/lib-network/include/net/apps/mdns.h @@ -0,0 +1,100 @@ +/** + * @file mdns.h + * + */ +/* Copyright (C) 2019-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_APPS_MDNS_H_ +#define NET_APPS_MDNS_H_ + +#include + +#include "network.h" +#include "net/protocol/dns.h" + +#include "../config/apps_config.h" + +namespace mdns { +enum class Services { + CONFIG, TFTP, HTTP, RDMNET_LLRP, NTP, MIDI, OSC, DDP, PP, LAST_NOT_USED +}; + +struct ServiceRecord { + char *pName; + char *pTextContent; + uint16_t nTextContentLength; + uint16_t nPort; + mdns::Services services; +}; +} // namespace mdns + +class MDNS { +public: + MDNS(); + ~MDNS(); + + bool ServiceRecordAdd(const char *pName, const mdns::Services service, const char *pTextContent = nullptr, const uint16_t nPort = 0); + bool ServiceRecordDelete(const mdns::Services service); + + void Print(); + + void SendAnnouncement(const uint32_t nTTL); + + void Run() { + s_nBytesReceived = Network::Get()->RecvFrom(s_nHandle, const_cast(reinterpret_cast(&s_pReceiveBuffer)), &s_nRemoteIp, &s_nRemotePort); + + if (__builtin_expect((s_nBytesReceived < sizeof(struct net::dns::Header)), 1)) { + return; + } + + const auto *const pHeader = reinterpret_cast(s_pReceiveBuffer); + const auto nFlag1 = pHeader->nFlag1; + + if ((nFlag1 >> 3) & 0xF) { + return; + } + + HandleQuestions(static_cast(__builtin_bswap16(pHeader->nQueryCount))); + } + + static MDNS *Get() { + return s_pThis; + } + +private: + void Parse(); + void HandleQuestions(const uint32_t nQuestions); + void SendAnswerLocalIpAddress(const uint16_t nTransActionID, const uint32_t nTTL); + void SendMessage(mdns::ServiceRecord const& serviceRecord, const uint16_t nTransActionID, const uint32_t nTTL); + void SendTo(const uint32_t nLength); + +private: + static int32_t s_nHandle; + static uint32_t s_nRemoteIp; + static uint32_t s_nBytesReceived; + static uint8_t *s_pReceiveBuffer; + static uint16_t s_nRemotePort; + + static MDNS *s_pThis; +}; + +#endif /* NET_APPS_MDNS_H_ */ diff --git a/lib-network/include/net/apps/ntpclient.h b/lib-network/include/net/apps/ntpclient.h new file mode 100755 index 0000000..1a1d526 --- /dev/null +++ b/lib-network/include/net/apps/ntpclient.h @@ -0,0 +1,147 @@ +/** + * @file ntpclient.h + * + */ +/* Copyright (C) 2019-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_APPS_NTPCLIENT_H_ +#define NET_APPS_NTPCLIENT_H_ + +#include +#include +#include + +#include "net/protocol/ntp.h" +#include "hardware.h" + +#include "debug.h" + +#if !defined(CONFIG_NTP_CLIENT_POLL_POWER) +# define CONFIG_NTP_CLIENT_POLL_POWER 10 +#endif + +namespace ntpclient { +static constexpr uint32_t TIMEOUT_MILLIS = 3000; +static constexpr uint8_t POLL_POWER = CONFIG_NTP_CLIENT_POLL_POWER; +static constexpr uint32_t POLL_SECONDS = (1U << POLL_POWER); + +void display_status(const ::ntp::Status status); +} // namespace ntpclient + +class NtpClient { +public: + NtpClient(); + + void Start(); + void Stop(); + void Print(); + + void SetServerIp(const uint32_t nServerIp) { + m_nServerIp = nServerIp; + } + + ntp::Status GetStatus() const { + return m_Status; + } + + void Run() { + if (m_Status == ntp::Status::STOPPED) { + return; + } + + if ((m_Status == ntp::Status::IDLE) || (m_Status == ntp::Status::FAILED)) { + if (__builtin_expect(((Hardware::Get()->Millis() - m_MillisLastPoll) > (1000 * ntpclient::POLL_SECONDS)), 0)) { + Send(); + m_MillisRequest = Hardware::Get()->Millis(); + m_Status = ntp::Status::WAITING; + ntpclient::display_status(ntp::Status::WAITING); + DEBUG_PUTS("ntp::Status::WAITING"); + } + + return; + } + + if (m_Status == ntp::Status::WAITING) { + uint8_t LiVnMode; + + if (!Receive(LiVnMode)) { + if (__builtin_expect(((Hardware::Get()->Millis() - m_MillisRequest) > ntpclient::TIMEOUT_MILLIS), 0)) { + m_Status = ntp::Status::FAILED; + ntpclient::display_status(ntp::Status::FAILED); + DEBUG_PUTS("ntp::Status::FAILED"); + } + + return; + } + + if (__builtin_expect(((LiVnMode & ntp::MODE_SERVER) == ntp::MODE_SERVER), 1)) { + m_MillisLastPoll = Hardware::Get()->Millis(); + + SetTimeOfDay(); +#ifndef NDEBUG + const auto nTime = time(nullptr); + const auto *pLocalTime = localtime(&nTime); + DEBUG_PRINTF("localtime: %.4d/%.2d/%.2d %.2d:%.2d:%.2d", pLocalTime->tm_year + 1900, pLocalTime->tm_mon + 1, pLocalTime->tm_mday, pLocalTime->tm_hour, pLocalTime->tm_min, pLocalTime->tm_sec); +#endif + } else { + DEBUG_PUTS("!>> Invalid reply < +#include namespace tftp { enum class Mode { @@ -70,11 +71,11 @@ class TFTPDaemon { int m_nIdx { -1 }; uint8_t *m_pBuffer { nullptr }; uint32_t m_nFromIp { 0 }; + uint32_t m_nLength { 0 }; + uint32_t m_nDataLength { 0 }; + uint32_t m_nPacketLength { 0 }; uint16_t m_nFromPort { 0 }; - size_t m_nLength { 0 }; uint16_t m_nBlockNumber { 0 }; - size_t m_nDataLength { 0 }; - uint16_t m_nPacketLength { 0 }; bool m_bIsLastBlock { false }; static TFTPDaemon* Get() { @@ -85,4 +86,4 @@ class TFTPDaemon { static TFTPDaemon *s_pThis; }; -#endif /* TFTPDAEMON_H_ */ +#endif /* NET_APPS_TFTPDAEMON_H_ */ diff --git a/lib-network/src/net/net_debug.h b/lib-network/include/net/arp.h old mode 100644 new mode 100755 similarity index 60% rename from lib-network/src/net/net_debug.h rename to lib-network/include/net/arp.h index 85095c4..cddb33d --- a/lib-network/src/net/net_debug.h +++ b/lib-network/include/net/arp.h @@ -1,8 +1,8 @@ /** - * @file net_debug.h + * @file arp_private.h * */ -/* Copyright (C) 2018-2019 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,22 +23,29 @@ * THE SOFTWARE. */ -#ifndef NET_DEBUG_H_ -#define NET_DEBUG_H_ +#ifndef ARP_PRIVATE_H_ +#define ARP_PRIVATE_H_ -#include "debug.h" +#include "netif.h" +#include "net/protocol/ip4.h" +#include "net/protocol/arp.h" +#include "net/protocol/udp.h" -#ifndef IP2STR - #define IP2STR(addr) (addr & 0xFF), ((addr >> 8) & 0xFF), ((addr >> 16) & 0xFF), ((addr >> 24) & 0xFF) - #define IPSTR "%d.%d.%d.%d" -#endif -#ifndef MAC2STR - #define MAC2STR(mac) (mac[0]),(mac[1]),(mac[2]),(mac[3]), (mac[4]), (mac[5]) - #define MACSTR "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" -#endif +namespace net { +namespace arp { +enum class Flags { + FLAG_INSERT, FLAG_UPDATE +}; +} // namespace arp -#if defined (H3) -# include "h3_timer.h" +void arp_init(); +void arp_handle(struct t_arp *); +void arp_send(struct t_udp *, const uint32_t, const uint32_t); +#if defined CONFIG_ENET_ENABLE_PTP +void arp_send_timestamp(struct t_udp *, const uint32_t, const uint32_t); #endif +void arp_acd_probe(const ip4_addr_t ipaddr); +void arp_acd_send_announcement(const ip4_addr_t ipaddr); +} // namespace net -#endif /* NET_DEBUG_H_ */ +#endif /* ARP_PRIVATE_H_ */ diff --git a/lib-network/include/net/autoip.h b/lib-network/include/net/autoip.h new file mode 100755 index 0000000..332fd7d --- /dev/null +++ b/lib-network/include/net/autoip.h @@ -0,0 +1,90 @@ +/** + * @file autoip.h + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* This code is inspired by the lwIP TCP/IP stack. + * https://savannah.nongnu.org/projects/lwip/ + */ +/** + * The autoip.cpp aims to be conform to RFC 3927. + * https://datatracker.ietf.org/doc/html/rfc3927 + * Dynamic Configuration of IPv4 Link-Local Addresses + */ + +#ifndef NET_AUTOIP_H_ +#define NET_AUTOIP_H_ + +#include + +#include "netif.h" +#include "net/acd.h" +#include "net/protocol/autoip.h" + +#include "debug.h" + +namespace net { +namespace autoip { +struct Autoip { + ip4_addr_t llipaddr; + State state; + uint8_t tried_llipaddr; + acd::Acd acd; +}; +} // namespace autoip + +void autoip_start(); +void autoip_stop(); + +inline bool autoip_supplied_address() { + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + + return (autoip != nullptr) + && (globals::netif_default.ip.addr == autoip->llipaddr.addr) + && (autoip->state == autoip::State::AUTOIP_STATE_BOUND); +} + +inline void autoip_network_changed_link_up() { + DEBUG_ENTRY + + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + + if ((autoip != nullptr) && (autoip->state != autoip::State::AUTOIP_STATE_OFF)) { + acd_start(&autoip->acd, autoip->llipaddr); + } + + DEBUG_EXIT +} + +inline void autoip_network_changed_link_down() { + DEBUG_EXIT + + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + + if ((autoip != nullptr) && (autoip->state != autoip::State::AUTOIP_STATE_OFF)) { + autoip_stop(); + } + + DEBUG_EXIT +} +} // namespace net + +#endif /* NET_AUTOIP_H_ */ diff --git a/lib-network/include/net/dhcp.h b/lib-network/include/net/dhcp.h new file mode 100755 index 0000000..1c6f167 --- /dev/null +++ b/lib-network/include/net/dhcp.h @@ -0,0 +1,139 @@ +/** + * @file dhcp.h + * + */ +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_DHCP_H_ +#define NET_DHCP_H_ + +#include +#include + +#include + +#include "netif.h" +#include "acd.h" +#include "ip4_address.h" +#include "net/protocol/dhcp.h" +#include "net/protocol/iana.h" + +#include "debug.h" + +namespace net { +namespace dhcp { +static constexpr uint32_t DHCP_COARSE_TIMER_SECS = 60; +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +static constexpr uint32_t DHCP_COARSE_TIMER_MSECS = (DHCP_COARSE_TIMER_SECS * 1000UL); +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +static constexpr uint32_t DHCP_FINE_TIMER_MSECS = 500; + +#define DHCP_FLAG_SUBNET_MASK_GIVEN 0x01 +#define DHCP_AUTOIP_COOP_TRIES 9 + +enum class AutoipCoopState { + DHCP_AUTOIP_COOP_STATE_OFF = 0, + DHCP_AUTOIP_COOP_STATE_ON = 1 +}; + +typedef uint16_t dhcp_timeout_t; + +struct Dhcp { + int32_t nHandle; + uint32_t xid; + State state; + uint8_t tries; + uint8_t flags; + + dhcp_timeout_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + dhcp_timeout_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + dhcp_timeout_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + dhcp_timeout_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ + dhcp_timeout_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ + dhcp_timeout_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ + dhcp_timeout_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ + + ip4_addr_t server_ip_addr; + + struct Offered { + ip4_addr_t offered_ip_addr; + ip4_addr_t offered_sn_mask; + ip4_addr_t offered_gw_addr; + + uint32_t offered_t0_lease; /* lease period (in seconds) */ + uint32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + uint32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period) */ + }; + + Offered offered; + + acd::Acd acd; +}; +} // namespace dhcp + +bool dhcp_start(); +bool dhcp_renew(); +bool dhcp_release(); +void dhcp_stop(); +void dhcp_release_and_stop(); +void dhcp_inform(); +void dhcp_network_changed_link_up(); + +uint32_t udp_recv2(int, const uint8_t **, uint32_t *, uint16_t *); +void dhcp_process(const dhcp::Message *const, const uint32_t nSize); + +inline void dhcp_run() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + if (dhcp == nullptr) { + return; + } + + uint8_t *pResponse; + uint32_t nFromIp; + uint16_t nFromPort; + + const auto nSize = udp_recv2(dhcp->nHandle, const_cast(&pResponse), &nFromIp, &nFromPort); + + if (__builtin_expect((nSize > 0), 0)) { + if (nFromPort == net::iana::IANA_PORT_DHCP_SERVER) { + const auto *const p = reinterpret_cast(pResponse); + + if (p->xid != dhcp->xid) { + DEBUG_PRINTF("pDhcpMessage->xid=%u, dhcp->xid=%u", p->xid, dhcp->xid); + return; + } + + dhcp_process(p, nSize); + } + } +} + +inline bool dhcp_supplied_address() { + const auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + if ((dhcp != nullptr)) { + return (dhcp->state == dhcp::State::STATE_BOUND) || (dhcp->state == dhcp::State::STATE_RENEWING) || (dhcp->state == dhcp::State::STATE_REBINDING); + } + return false; +} +} // namespace net + +#endif /* NET_DHCP_H_ */ diff --git a/lib-network/include/net/igmp.h b/lib-network/include/net/igmp.h new file mode 100755 index 0000000..252cce6 --- /dev/null +++ b/lib-network/include/net/igmp.h @@ -0,0 +1,13 @@ +/* + * igmp.h + */ + +#ifndef NET_IGMP_H_ +#define NET_IGMP_H_ + +namespace net { +//TODO implement +void igmp_report_groups(); +} // namespace net + +#endif /* NET_IGMP_H_ */ diff --git a/lib-network/include/net/protocol/acd.h b/lib-network/include/net/protocol/acd.h new file mode 100644 index 0000000..035b3e5 --- /dev/null +++ b/lib-network/include/net/protocol/acd.h @@ -0,0 +1,64 @@ +/** + * @file acd.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_ACD_H_ +#define NET_PROTOCOL_ACD_H_ + +#include + +namespace net::acd { +/** + * RFC 5227 and RFC 3927 Constants + */ +#define PROBE_WAIT 1 ///< second (initial random delay) +#define PROBE_MIN 1 ///< second (minimum delay till repeated probe) +#define PROBE_MAX 2 ///< seconds (maximum delay till repeated probe) +#define PROBE_NUM 3 ///< (number of probe packets) +#define ANNOUNCE_NUM 2 ///< (number of announcement packets) +#define ANNOUNCE_INTERVAL 2 ///< seconds (time between announcement packets) +#define ANNOUNCE_WAIT 2 ///< seconds (delay before announcing) +#define MAX_CONFLICTS 10 ///< (max conflicts before rate limiting) +#define RATE_LIMIT_INTERVAL 60 ///< seconds (delay between successive attempts) +#define DEFEND_INTERVAL 10 ///< seconds (minimum interval between defensive ARPs) + +enum class State: uint8_t { + ACD_STATE_OFF, + ACD_STATE_PROBE_WAIT, + ACD_STATE_PROBING, + ACD_STATE_ANNOUNCE_WAIT, + ACD_STATE_ANNOUNCING, + ACD_STATE_ONGOING, + ACD_STATE_PASSIVE_ONGOING, + ACD_STATE_RATE_LIMIT +}; + +enum class Callback { + ACD_IP_OK, ///< IP address is good, no conflicts found in checking state + ACD_RESTART_CLIENT, ///< Conflict found -> the client should try again + ACD_DECLINE ///< Decline the received IP address (rate limiting) +}; +} // namespace acd + +#endif /* NET_PROTOCOL_ACD_H_ */ diff --git a/lib-network/include/mdnsservices.h b/lib-network/include/net/protocol/arp.h old mode 100644 new mode 100755 similarity index 50% rename from lib-network/include/mdnsservices.h rename to lib-network/include/net/protocol/arp.h index 9032b8d..3d6b6b1 --- a/lib-network/include/mdnsservices.h +++ b/lib-network/include/net/protocol/arp.h @@ -1,8 +1,8 @@ /** - * @file mdnsservices.h + * @file arp.h * */ -/* Copyright (C) 2019-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,17 +23,54 @@ * THE SOFTWARE. */ -#ifndef MDNSSERVICES_H_ -#define MDNSSERVICES_H_ +#ifndef NET_PROTOCOL_ARP_H_ +#define NET_PROTOCOL_ARP_H_ -#define MDNS_SERVICE_MIDI "._apple-midi" -#define MDNS_SERVICE_OSC "._osc" -#define MDNS_SERVICE_CONFIG "._config" -#define MDNS_SERVICE_TFTP "._tftp" -#define MDNS_SERVICE_NTP "._ntp" -#define MDNS_SERVICE_DDP "._ddp" -#define MDNS_SERVICE_PP "._pp" -#define MDNS_SERVICE_HTTP "._http" -#define MDNS_SERVICE_RDMNET_LLRP "._rdmnet-llrp" +#include "ip4_address.h" +#include "net/protocol/ethernet.h" +#include "net/protocol/ieee.h" -#endif /* MDNSSERVICES_H_ */ +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif + +enum ARP_HARDWARE_TYPE { + ARP_HWTYPE_ETHERNET = 1 +}; + +enum ARP_PROTOCOL_TYPE { + ARP_PRTYPE_IPv4 = ETHER_TYPE_IPv4 +}; + +enum ARP_HARDWARE { + ARP_HARDWARE_SIZE = ETH_ADDR_LEN +}; + +enum ARP_PROTOCOL { + ARP_PROTOCOL_SIZE = IPv4_ADDR_LEN +}; + +enum ARP_OPCODE { + ARP_OPCODE_RQST = 1, + ARP_OPCODE_REPLY = 2 +}; + +struct arp_packet { + uint16_t hardware_type; /* 2 */ + uint16_t protocol_type; /* 4 */ + uint8_t hardware_size; /* 5 */ + uint8_t protocol_size; /* 6 */ + uint16_t opcode; /* 8 */ + uint8_t sender_mac[ETH_ADDR_LEN];/*14 */ + uint8_t sender_ip[IPv4_ADDR_LEN];/* 18 */ + uint8_t target_mac[ETH_ADDR_LEN];/*24 */ + uint8_t target_ip[IPv4_ADDR_LEN];/* 28 */ + uint8_t padding[18]; /* 46 */ /* +14 = 60 */ +} PACKED; + +struct t_arp { + struct ether_header ether; + struct arp_packet arp; +} PACKED; + +#endif /* NET_PROTOCOL_ARP_H_ */ diff --git a/lib-network/include/net/protocol/autoip.h b/lib-network/include/net/protocol/autoip.h new file mode 100644 index 0000000..dc3d900 --- /dev/null +++ b/lib-network/include/net/protocol/autoip.h @@ -0,0 +1,43 @@ +/** + * @file autoip.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_AUTOIP_H_ +#define NET_PROTOCOL_AUTOIP_H_ + +#include "ip4_address.h" + +namespace net::autoip { +static constexpr auto AUTOIP_NET = network::convert_to_uint(169,254,0,0); +static constexpr auto AUTOIP_RANGE_START = network::convert_to_uint(169,254,1,0); +static constexpr auto AUTOIP_RANGE_END = network::convert_to_uint(169,254,254,255); + +enum class State { + AUTOIP_STATE_OFF, + AUTOIP_STATE_CHECKING, + AUTOIP_STATE_BOUND +}; +} // namespace autoip + +#endif /* NET_PROTOCOL_AUTOIP_H_ */ diff --git a/lib-network/include/net/protocol/dhcp.h b/lib-network/include/net/protocol/dhcp.h new file mode 100644 index 0000000..9406417 --- /dev/null +++ b/lib-network/include/net/protocol/dhcp.h @@ -0,0 +1,120 @@ +/** + * @file dhcp.h + * + */ +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_DHCP_H +#define NET_PROTOCOL_DHCP_H + +#include + +#include "ip4.h" + +namespace net::dhcp { +static constexpr uint32_t OPT_SIZE = 312; +static constexpr uint32_t MAGIC_COOKIE = 0x63825363; ///< You should not modify it number. + +struct OpCode { + static constexpr uint8_t BOOTREQUEST = 1; + static constexpr uint8_t BOOTREPLY = 2; +}; + +struct HardwareType { + static constexpr uint8_t HTYPE_10MB = 1; + static constexpr uint8_t HTYPE_100MB = 2; +}; + +struct Type { + static constexpr uint8_t DISCOVER = 1; + static constexpr uint8_t OFFER = 2; + static constexpr uint8_t REQUEST = 3; + static constexpr uint8_t DECLINE = 4; + static constexpr uint8_t ACK = 5; + static constexpr uint8_t NAK = 6; + static constexpr uint8_t RELEASE = 7; + static constexpr uint8_t INFORM = 8; +}; + +struct Options { + /* BootP options */ + static constexpr uint8_t OPTION_PAD_OPTION = 0; + static constexpr uint8_t OPTION_SUBNET_MASK = 1; ///< RFC 2132 3.3 + static constexpr uint8_t OPTION_ROUTER = 3; + static constexpr uint8_t OPTION_DNS_SERVER = 6; + static constexpr uint8_t OPTION_HOSTNAME = 12; + static constexpr uint8_t OPTION_DOMAIN_NAME = 15; + static constexpr uint8_t OPTION_IP_TTL = 23; + static constexpr uint8_t OPTION_MTU = 26; + static constexpr uint8_t OPTION_BROADCAST = 28; + static constexpr uint8_t OPTION_TCP_TTL = 37; + static constexpr uint8_t OPTION_NTP = 42; + static constexpr uint8_t OPTION_END = 255; + /* DHCP options */ + static constexpr uint8_t OPTION_REQUESTED_IP = 50; ///< RFC 2132 9.1, requested IP address + static constexpr uint8_t OPTION_LEASE_TIME = 51; ///< RFC 2132 9.2, time in seconds, in 4 bytes + static constexpr uint8_t OPTION_OVERLOAD = 52; ///< RFC2132 9.3, use file and/or sname field for options + static constexpr uint8_t OPTION_MESSAGE_TYPE = 53; ///< RFC 2132 9.6, important for DHCP + static constexpr uint8_t OPTION_SERVER_IDENTIFIER = 54; ///< RFC 2132 9.7, server IP address + static constexpr uint8_t OPTION_PARAM_REQUEST = 55; ///< RFC 2132 9.8, requested option types + static constexpr uint8_t OPTION_MAX_MSG_SIZE = 57; ///< RFC 2132 9.10, message size accepted >= 576 + static constexpr uint8_t OPTION_DHCP_T1_VALUE = 58; ///< T1 renewal time + static constexpr uint8_t OPTION_DHCP_T2_VALUE = 59; ///< T2 renewal time + static constexpr uint8_t OPTION_CLIENT_IDENTIFIER = 61; +}; + +enum class State: uint8_t { + STATE_OFF = 0, + STATE_REQUESTING = 1, + STATE_INIT = 2, + STATE_REBOOTING = 3, + STATE_REBINDING = 4, + STATE_RENEWING = 5, + STATE_SELECTING = 6, + STATE_INFORMING = 7, + STATE_CHECKING = 8, + STATE_PERMANENT = 9, + STATE_BOUND = 10, + STATE_RELEASING = 11, + STATE_BACKING_OFF = 12 +}; + +struct Message { + uint8_t op; + uint8_t htype; + uint8_t hlen; + uint8_t hops; + uint32_t xid; + uint16_t secs; + uint16_t flags; + uint8_t ciaddr[IPv4_ADDR_LEN]; + uint8_t yiaddr[IPv4_ADDR_LEN]; + uint8_t siaddr[IPv4_ADDR_LEN]; + uint8_t giaddr[IPv4_ADDR_LEN]; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint8_t options[dhcp::OPT_SIZE]; +} __attribute__((packed)); +} // namespace net::dhcp + +#endif /* NET_PROTOCOL_DHCP_H */ diff --git a/lib-network/include/net/protocol/dns.h b/lib-network/include/net/protocol/dns.h new file mode 100644 index 0000000..e486563 --- /dev/null +++ b/lib-network/include/net/protocol/dns.h @@ -0,0 +1,93 @@ +/** + * @file dns.h + * + */ +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_DNS_H_ +#define NET_PROTOCOL_DNS_H_ + +#include + +#include "ip4_address.h" + +namespace net { namespace dns { +static constexpr uint32_t SIZEOF_DNS_HDR = 12; + +enum class Flag1 : uint8_t { + FLAG1_RESPONSE = 0x80, ///< query (0), or a response (1). + FLAG1_OPCODE_STATUS = 0x10, ///< a server status request (STATUS) + FLAG1_OPCODE_IQUERY = 0x08, ///< an inverse query (IQUERY) + FLAG1_OPCODE_STANDARD = 0x00, ///< (RFC 6762, section 18.3) + FLAG1_AUTHORATIVE = 0x04, ///< Authoritative Answer + FLAG1_TRUNC = 0x02, ///< TrunCation + FLAG1_RD = 0x01 ///< If RD is set, it directs the name server to pursue the query recursively. +}; + +static constexpr uint8_t operator| (Flag1 a, Flag1 b) { + return static_cast((static_cast(a) | static_cast(b))); +} + +///< NS field TYPE used for "Resource Records" +enum class RRType : uint16_t { + RRTYPE_A = 1, ///< a host address + RRTYPE_PTR = 12, ///< a domain name pointer + RRTYPE_TXT = 16, ///< text strings + RRTYPE_SRV = 33, ///< service location + RRTYPE_ALL = 255 ///< any type +}; + +///< DNS field CLASS used for "Resource Records" +enum class RRClass : uint16_t { + RRCLASS_INTERNET = 1, ///< Internet + RRCLASS_ANY = 255, ///< Any class + RRCLASS_FLUSH = 0x8000 ///< Flush bit +}; + +static constexpr uint16_t operator| (RRClass a, RRClass b) { + return static_cast((static_cast(a) | static_cast(b))); +} + +struct Header { + uint16_t xid; + uint8_t nFlag1; + uint8_t nFlag2; + uint16_t nQueryCount; + uint16_t nAnswerCount; + uint16_t nAuthorityCount; + uint16_t nAdditionalCount; +} __attribute__((__packed__)); + +inline uint8_t dns_header_get_opcode(const Header *const header) { + return ((header->nFlag1) >> 3) & 0xF; +} + +/* + * mDNS + */ + +static constexpr uint32_t MULTICAST_MESSAGE_SIZE = 512; ///< The 1987 DNS specification [RFC1035] restricts DNS messages carried by UDP to no more than 512 bytes +static constexpr uint32_t MULTICAST_ADDRESS = network::convert_to_uint(224, 0, 0, 251); + +} } // namespace net::dns + +#endif /* NET_PROTOCOL_DNS_H_ */ diff --git a/lib-network/src/emac/gd32/net.c b/lib-network/include/net/protocol/ethernet.h old mode 100644 new mode 100755 similarity index 67% rename from lib-network/src/emac/gd32/net.c rename to lib-network/include/net/protocol/ethernet.h index 5c180de..323c233 --- a/lib-network/src/emac/gd32/net.c +++ b/lib-network/include/net/protocol/ethernet.h @@ -1,8 +1,8 @@ /** - * net.c + * @file ethernet.h * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,27 +23,33 @@ * THE SOFTWARE. */ +#ifndef NET_PROTOCOL_ETHERNET_H_ +#define NET_PROTOCOL_ETHERNET_H_ + #include -#include "gd32.h" +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif + +enum MTU { + MTU_SIZE = 1500 +}; -extern enet_descriptors_struct *dma_current_rxdesc; +enum ETH_ADDR { + ETH_ADDR_LEN = 6 +}; -int emac_eth_recv(uint8_t **packet) { - const uint32_t size = enet_rxframe_size_get(); +struct ether_header { + uint8_t dst[ETH_ADDR_LEN]; /* 6 */ + uint8_t src[ETH_ADDR_LEN]; /* 12 */ + uint16_t type; /* 14 */ +} PACKED; - if (size > 0) { - *packet = (uint8_t *) (enet_desc_information_get(dma_current_rxdesc, RXDESC_BUFFER_1_ADDR)); - return size; - } +namespace net { +static constexpr uint32_t ETH_HWADDR_LEN = 6; - return -1; -} -void emac_free_pkt(void) { - ENET_NOCOPY_FRAME_RECEIVE(); -} +} // namespace net -void emac_eth_send(void *packet, int len) { - enet_frame_transmit((uint8_t *) packet, len); -} +#endif /* NET_PROTOCOL_ETHERNET_H_ */ diff --git a/lib-network/src/net/net_timers.cpp b/lib-network/include/net/protocol/iana.h similarity index 66% rename from lib-network/src/net/net_timers.cpp rename to lib-network/include/net/protocol/iana.h index ef8a35c..bc5c699 100644 --- a/lib-network/src/net/net_timers.cpp +++ b/lib-network/include/net/protocol/iana.h @@ -1,8 +1,8 @@ /** - * @file net_timers.cpp + * @file iana.h * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,30 +23,18 @@ * THE SOFTWARE. */ -#include - -#include "net_private.h" - -#include "hardware.h" - -#include "../../config/net_config.h" +#ifndef NET_PROTOCOL_IANA_H_ +#define NET_PROTOCOL_IANA_H_ -#ifndef NDEBUG - extern void arp_cache_timer(void); -#endif - -static volatile uint32_t s_ticker; - -#define INTERVAL_MS (100) // 100 msec, 1/10 second +#include -void net_timers_run() { - const auto nMillis = Hardware::Get()->Millis(); +namespace net::iana { +static constexpr uint16_t IANA_PORT_DHCP_SERVER = 67; +static constexpr uint16_t IANA_PORT_DHCP_CLIENT = 68; +static constexpr uint16_t IANA_PORT_TFTP = 69; +static constexpr uint16_t IANA_PORT_HTTP = 80; +static constexpr uint16_t IANA_PORT_NTP_SERVER = 123; +static constexpr uint16_t IANA_PORT_MDNS = 5353; +} // namespace net::iana - if (__builtin_expect((nMillis >= s_ticker), 0)) { - s_ticker = nMillis + INTERVAL_MS; - igmp_timer(); -#ifndef NDEBUG - arp_cache_timer(); -#endif - } -} +#endif /* NET_PROTOCOL_IANA_H_ */ diff --git a/lib-network/src/net/dhcp_internal.h b/lib-network/include/net/protocol/icmp.h old mode 100644 new mode 100755 similarity index 54% rename from lib-network/src/net/dhcp_internal.h rename to lib-network/include/net/protocol/icmp.h index 1ce0e73..a9cb2a8 --- a/lib-network/src/net/dhcp_internal.h +++ b/lib-network/include/net/protocol/icmp.h @@ -1,8 +1,8 @@ /** - * @file dhcp_internal.h + * @file icmp.h * */ -/* Copyright (C) 2018-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,47 +23,43 @@ * THE SOFTWARE. */ -#ifndef DHCP_INTERNAL_H_ -#define DHCP_INTERNAL_H_ +#ifndef NET_PROTOCOL_ICMP_H_ +#define NET_PROTOCOL_ICMP_H_ -enum DHCP_PORT { - DHCP_PORT_SERVER = 67, - DHCP_PORT_CLIENT = 68 -}; +#include -enum DHCP_OP { - DHCP_OP_BOOTREQUEST = 1, - DHCP_OP_BOOTREPLY = 2 -}; +#include "net/protocol/ethernet.h" +#include "net/protocol/ip4.h" -enum DHCP_HTYPE { - DHCP_HTYPE_10MB = 1, - DHCP_HTYPE_100MB = 2 -}; +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif -enum DCHP_TYPE { - DCHP_TYPE_DISCOVER = 1, - DCHP_TYPE_OFFER = 2, - DCHP_TYPE_REQUEST = 3, - DCHP_TYPE_DECLINE = 4, - DCHP_TYPE_ACK = 5, - DCHP_TYPE_NAK = 6, - DCHP_TYPE_RELEASE = 7, - DCHP_TYPE_INFORM = 8 +enum ICMP_TYPE { + ICMP_TYPE_ECHO_REPLY = 0, + ICMP_TYPE_ECHO = 8 }; -enum DHCP_STATE { - DHCP_STATE_DHCP_INIT = 0, - DHCP_STATE_DHCP_DISCOVER = 1, - DHCP_STATE_DHCP_REQUEST = 2, - DHCP_STATE_DHCP_LEASED = 3, - DHCP_STATE_DHCP_REREQUEST = 4, - DHCP_STATE_DHCP_RELEASE = 5, - DHCP_STATE_DHCP_STOP = 6 +enum ICMP_CODE { + ICMP_CODE_ECHO = 0 }; -#define DHCP_OPT_SIZE 312 +struct t_icmp_packet { + uint8_t type; /* 1 */ + uint8_t code; /* 2 */ + uint16_t checksum; /* 4 */ + uint8_t parameter[4]; /* 8 */ +#define ICMP_HEADER_SIZE 8 +#define ICMP_PAYLOAD_SIZE (MTU_SIZE - ICMP_HEADER_SIZE - sizeof(struct ip4_header)) + uint8_t payload[ICMP_PAYLOAD_SIZE]; +} PACKED; + +struct t_icmp { + struct ether_header ether; + struct ip4_header ip4; + struct t_icmp_packet icmp; +} PACKED; -#define MAGIC_COOKIE 0x63825363 ///< You should not modify it number. +#define IPv4_ICMP_HEADERS_SIZE (sizeof(struct t_icmp) - sizeof(struct ether_header)) -#endif /* DHCP_INTERNAL_H_ */ +#endif /* NET_PROTOCOL_ICMP_H_ */ diff --git a/lib-network/include/net/protocol/ieee.h b/lib-network/include/net/protocol/ieee.h new file mode 100755 index 0000000..c65ef05 --- /dev/null +++ b/lib-network/include/net/protocol/ieee.h @@ -0,0 +1,37 @@ +/** + * @file ieee.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_IEEE_H_ +#define NET_PROTOCOL_IEEE_H_ + +#include + +enum ETHER_TYPE { + ETHER_TYPE_IPv4 = 0x0800, + ETHER_TYPE_ARP = 0x0806, + ETHER_TYPE_PTP = 0x88F7 /* IEEE1588v2 (PTPv2) over Ethernet */ +}; + +#endif /* NET_PROTOCOL_IEEE_H_ */ diff --git a/lib-hal/src/utc.cpp b/lib-network/include/net/protocol/igmp.h old mode 100644 new mode 100755 similarity index 55% rename from lib-hal/src/utc.cpp rename to lib-network/include/net/protocol/igmp.h index ba6e01b..d49a7d9 --- a/lib-hal/src/utc.cpp +++ b/lib-network/include/net/protocol/igmp.h @@ -1,8 +1,8 @@ /** - * @file utc.cpp + * @file igmp.h * */ -/* Copyright (C) 2019-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -10,8 +10,10 @@ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: + * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,28 +23,44 @@ * THE SOFTWARE. */ +#ifndef NET_PROTOCOL_IGMP_H_ +#define NET_PROTOCOL_IGMP_H_ + #include -#include "utc.h" +#include "net/protocol/ethernet.h" +#include "net/protocol/ip4.h" + +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif -// https://en.wikipedia.org/wiki/List_of_UTC_time_offsets +enum IGMP_TYPE { + IGMP_TYPE_QUERY = 0x11, + IGMP_TYPE_REPORT = 0x16, + IGMP_TYPE_LEAVE = 0x17 +}; -static const float s_ValidOffets[] = { -9.5, -3.5, 3.5, 4.5, 5.5, 5.75, 6.5, 8.75, 9.5, 10.5, 12.75 }; +struct t_igmp_packet { + uint8_t type; + uint8_t max_resp_time; + uint16_t checksum; + uint8_t group_address[IPv4_ADDR_LEN]; +} PACKED; -int32_t Utc::Validate(float fOffset) { - auto nInt = static_cast(fOffset); +struct t_igmp { + struct ether_header ether; + struct ip4_header ip4; + union { + struct { + uint32_t ip4_options; + struct t_igmp_packet igmp; + } report; + struct t_igmp_packet igmp; + } igmp; +} PACKED; - if ((nInt >= -12) && (nInt <= 14)) { - if (fOffset == static_cast(nInt)) { - return (nInt * 3600); - } else { - for (uint32_t i = 0; i < sizeof(s_ValidOffets) / sizeof(s_ValidOffets[0]); i++) { - if (fOffset == s_ValidOffets[i]) { - return static_cast(fOffset * 3600.0f); - } - } - } - } +#define IPv4_IGMP_REPORT_HEADERS_SIZE (sizeof(struct t_igmp) - sizeof(struct ether_header)) +#define IGMP_REPORT_PACKET_SIZE (sizeof(struct t_igmp)) - return 0; -} +#endif /* NET_PROTOCOL_IGMP_H_ */ diff --git a/lib-network/include/net/protocol/ip4.h b/lib-network/include/net/protocol/ip4.h new file mode 100755 index 0000000..346b997 --- /dev/null +++ b/lib-network/include/net/protocol/ip4.h @@ -0,0 +1,71 @@ +/** + * @file ip4.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef NET_PROTOCOL_IP4_H_ +#define NET_PROTOCOL_IP4_H_ + +#include + +#include "net/protocol/ethernet.h" + +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif + +enum IPv4_ADDR { + IPv4_ADDR_LEN = 4 +}; + +enum IPv4_PROTO { + IPv4_PROTO_ICMP = 1, + IPv4_PROTO_IGMP = 2, + IPv4_PROTO_TCP = 6, + IPv4_PROTO_UDP = 17 +}; + +enum IPv4_FLAG { + IPv4_FLAG_LF = 0x0000, + IPv4_FLAG_MF = 0x2000, + IPv4_FLAG_DF = 0x4000 +}; + +struct ip4_header { + uint8_t ver_ihl; /* 1 */ + uint8_t tos; /* 2 */ + uint16_t len; /* 4 */ + uint16_t id; /* 6 */ + uint16_t flags_froff; /* 8 */ + uint8_t ttl; /* 9 */ + uint8_t proto; /* 10 */ + uint16_t chksum; /* 12 */ + uint8_t src[IPv4_ADDR_LEN]; /* 16 */ + uint8_t dst[IPv4_ADDR_LEN]; /* 20 */ +} PACKED; + +struct t_ip4 { + struct ether_header ether; + struct ip4_header ip4; +} PACKED; + +#endif /* NET_PROTOCOL_IP4_H_ */ diff --git a/lib-network/include/ntp.h b/lib-network/include/net/protocol/ntp.h old mode 100644 new mode 100755 similarity index 50% rename from lib-network/include/ntp.h rename to lib-network/include/net/protocol/ntp.h index fdf6b0d..2999c4c --- a/lib-network/include/ntp.h +++ b/lib-network/include/net/protocol/ntp.h @@ -2,7 +2,7 @@ * @file ntp.h * */ -/* Copyright (C) 2019-2020 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2019-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,34 +23,23 @@ * THE SOFTWARE. */ -#ifndef NTP_H_ -#define NTP_H_ +#ifndef NET_PROTOCOL_NTP_H_ +#define NET_PROTOCOL_NTP_H_ -static constexpr auto LOCAL_TIME_YEAR_OFFSET = 1900; -static constexpr auto NTP_TIMESTAMP_DELTA = 2208988800u; +#include -enum TNtpUdpPort { - NTP_UDP_PORT = 123 -}; - -enum TNtpVersion { - NTP_VERSION = (4 << 3) -}; +namespace ntp { +static constexpr uint32_t JAN_1970 = 0x83aa7e80; // 2208988800 1970 - 1900 in seconds +static constexpr uint32_t LOCAL_TIME_YEAR_OFFSET = 1900; +static constexpr uint32_t MICROSECONDS_IN_SECOND = 1000000; +static constexpr uint16_t UDP_PORT = 123; +static constexpr uint8_t VERSION = (4U << 3); +static constexpr uint8_t MODE_CLIENT = (3U << 0); +static constexpr uint8_t MODE_SERVER = (4U << 0); +static constexpr uint8_t STRATUM = 2; +static constexpr uint8_t MINPOLL = 4; -enum TNtpMode { - NTP_MODE_CLIENT = (3 << 0), - NTP_MODE_SERVER = (4 << 0) -}; - -enum TNtpStratum { - NTP_STRATUM = 2 -}; - -enum TNtpPoll { - NTP_MINPOLL = 4 -}; - -struct TNtpPacket { +struct Packet { uint8_t LiVnMode; uint8_t Stratum; uint8_t Poll; @@ -68,4 +57,45 @@ struct TNtpPacket { uint32_t TransmitTimestamp_f; }__attribute__((packed)); -#endif /* NTP_H_ */ +struct TimeStamp { + uint32_t nSeconds; + uint32_t nFraction; +}; + +struct time_t { + int32_t tv_sec; + int32_t tv_usec; +}; + +enum class Status { + STOPPED, IDLE, WAITING, FAILED +}; + +static constexpr char STATUS[4][8] = { "Stopped", "Idle", "Waiting", "Failed" }; + +enum class Modes { + BASIC, INTERLEAVED, UNKNOWN +}; + +inline void normalize_time(ntp::time_t *r) { + r->tv_sec += r->tv_usec / 1000000; + r->tv_usec -= r->tv_usec / 1000000 * 1000000; + + if (r->tv_sec > 0 && r->tv_usec < 0) { + r->tv_sec -= 1; + r->tv_usec += 1000000; + } else if (r->tv_sec < 0 && r->tv_usec > 0) { + r->tv_sec += 1; + r->tv_usec -= 1000000; + } +} + +inline void sub_time(struct ntp::time_t *r, const struct ntp::time_t *x, const struct ntp::time_t *y) { + r->tv_sec = x->tv_sec - y->tv_sec; + r->tv_usec = x->tv_usec - y->tv_usec; + + normalize_time(r); +} +} // namespace ntp + +#endif /* NET_PROTOCOL_NTP_H_ */ diff --git a/lib-network/include/net/protocol/tcp.h b/lib-network/include/net/protocol/tcp.h new file mode 100755 index 0000000..b20047f --- /dev/null +++ b/lib-network/include/net/protocol/tcp.h @@ -0,0 +1,62 @@ +/** + * @file tcp.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NET_PROTOCOL_TCP_H_ +#define NET_PROTOCOL_TCP_H_ + +#include + +#include "net/protocol/ethernet.h" +#include "net/protocol/ip4.h" + +#if !defined (PACKED) +# define PACKED __attribute__((packed)) +#endif + +struct t_tcp_packet { + uint16_t srcpt; /* 2 */ + uint16_t dstpt; /* 4 */ + uint32_t seqnum; /* 8 */ + uint32_t acknum; /* 12 */ + uint8_t offset; /* 13 */ + uint8_t control; /* 14 */ + uint16_t window; /* 16 */ + uint16_t checksum; /* 18 */ + uint16_t urgent; /* 20 */ +#define TCP_HEADER_SIZE 20 +#define TCP_OPTIONS_SIZE 40 /* Assuming maximum TCP options size is 40 bytes */ +#define TCP_DATA_SIZE (MTU_SIZE - TCP_HEADER_SIZE - sizeof(struct ip4_header) - TCP_OPTIONS_SIZE) + uint8_t data[MTU_SIZE - TCP_HEADER_SIZE - sizeof(struct ip4_header)]; +} PACKED; + +struct t_tcp { + struct ether_header ether; + struct ip4_header ip4; + struct t_tcp_packet tcp; +} PACKED; + +#define IPv4_UDP_HEADERS_SIZE (sizeof(struct ip4_header) + UDP_HEADER_SIZE) /* IP | UDP */ + +#endif /* NET_PROTOCOL_TCP_H_ */ diff --git a/lib-gd32/include/gd32_micros.h b/lib-network/include/net/protocol/udp.h old mode 100644 new mode 100755 similarity index 58% rename from lib-gd32/include/gd32_micros.h rename to lib-network/include/net/protocol/udp.h index 14e654d..49bd5ec --- a/lib-gd32/include/gd32_micros.h +++ b/lib-network/include/net/protocol/udp.h @@ -1,8 +1,8 @@ /** - * @file gd32_micros.h + * @file udp.h * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,33 +23,34 @@ * THE SOFTWARE. */ -#ifndef GD32_MICROS_H_ -#define GD32_MICROS_H_ +#ifndef NET_PROTOCOL_UDP_H_ +#define NET_PROTOCOL_UDP_H_ #include -#include "gd32.h" +#include "net/protocol/ethernet.h" +#include "net/protocol/ip4.h" -#if defined (GD32F4XX) && !defined(MICROS_DO_NOT_USE_TIMER4) -static inline uint32_t micros() { - return TIMER_CNT(TIMER4); -} -#else -static inline uint32_t micros() { - static uint32_t nMicrosPrevious; - static uint32_t nResult; - const auto nMicros = DWT->CYCCNT / (MCU_CLOCK_FREQ / 1000000U); - - if (nMicros > nMicrosPrevious) { - nResult += (nMicros - nMicrosPrevious); - } else { - nResult += ((UINT32_MAX/ (MCU_CLOCK_FREQ / 1000000U)) - nMicrosPrevious + nMicros); - } - - nMicrosPrevious = nMicros; - - return nResult; -} +#if !defined (PACKED) +# define PACKED __attribute__((packed)) #endif -#endif /* GD32_MICROS_H_ */ +struct t_udp_packet { + uint16_t source_port; /* 2 */ + uint16_t destination_port; /* 4 */ + uint16_t len; /* 6 */ + uint16_t checksum; /* 8 */ +#define UDP_HEADER_SIZE 8 +#define UDP_DATA_SIZE (MTU_SIZE - UDP_HEADER_SIZE - sizeof(struct ip4_header)) + uint8_t data[UDP_DATA_SIZE]; +}PACKED; + +struct t_udp { + struct ether_header ether; + struct ip4_header ip4; + struct t_udp_packet udp; +} PACKED; + +#define UDP_PACKET_HEADERS_SIZE (sizeof(struct ether_header) + IPv4_UDP_HEADERS_SIZE) /* ETH | IP | UDP */ + +#endif /* NET_PROTOCOL_UDP_H_ */ diff --git a/lib-network/include/netif.h b/lib-network/include/netif.h new file mode 100755 index 0000000..5e7f5dc --- /dev/null +++ b/lib-network/include/netif.h @@ -0,0 +1,168 @@ +/** + * @file netif.h + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NETIF_H_ +#define NETIF_H_ + +#include + +#include "netif.h" +#include "ip4_address.h" + +#include "debug.h" + +#ifndef NETIF_MAX_HWADDR_LEN +# define NETIF_MAX_HWADDR_LEN 6U +#endif + +namespace net { +struct ip_addr { + uint32_t addr; +}; + +typedef struct ip_addr ip4_addr_t; + +struct netif { + static constexpr uint8_t NETIF_FLAG_LINK_UP = (1U << 0); + static constexpr uint8_t NETIF_FLAG_DHCP_OK = (1U << 1); + static constexpr uint8_t NETIF_FLAG_AUTOIP_OK = (1U << 2); + static constexpr uint8_t NETIF_FLAG_STATICIP_OK = (1U << 3); + + struct ip_addr ip; + struct ip_addr netmask; + struct ip_addr gw; + struct ip_addr broadcast_ip; + struct ip_addr secondary_ip; + + uint8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + uint8_t flags; + + const char *hostname; + + void *dhcp; + void *acd; + void *autoip; +}; + +struct NetifReason { + static constexpr uint16_t NSC_NONE = 0x0000; + static constexpr uint16_t NSC_LINK_CHANGED = 0x0004; + static constexpr uint16_t NSC_IPV4_ADDRESS_CHANGED = 0x0010; + static constexpr uint16_t NSC_IPV4_GATEWAY_CHANGED = 0x0020; + static constexpr uint16_t NSC_IPV4_NETMASK_CHANGED = 0x0040; + static constexpr uint16_t NSC_IPV4_SETTINGS_CHANGED = 0x0080; + static constexpr uint16_t NSC_IPV4_ADDR_VALID = 0x0400; +}; + +struct ipv4_changed { + ip4_addr_t old_address; + ip4_addr_t old_netmask; + ip4_addr_t old_gw; +}; + +struct link_changed { + /** 1: up; 0: down */ + uint8_t state; +} ; + +union netif_ext_callback_args_t { + struct link_changed link_changed; + struct ipv4_changed ipv4_changed; +}; + +namespace globals { +extern struct netif netif_default; +} // namespace globals + +typedef void (* netif_ext_callback_fn)(const uint16_t reason, const netif_ext_callback_args_t *args); + +inline void netif_set_flags(uint8_t flags) { + globals::netif_default.flags |= flags; +} + +inline void netif_clear_flags(uint8_t flags) { + globals::netif_default.flags &= static_cast(~flags); +} + +inline bool netif_dhcp() { + return (globals::netif_default.flags & netif::NETIF_FLAG_DHCP_OK) == netif::NETIF_FLAG_DHCP_OK; +} + +inline bool netif_autoip() { + return (globals::netif_default.flags & netif::NETIF_FLAG_AUTOIP_OK) == netif::NETIF_FLAG_AUTOIP_OK; +} + +inline uint32_t netif_ipaddr() { + return globals::netif_default.ip.addr; +} + +inline uint32_t netif_netmask() { + return globals::netif_default.netmask.addr; +} + +inline uint32_t netif_gw() { + return globals::netif_default.gw.addr; +} + +inline void netif_set_hostname(const char *hostname) { + globals::netif_default.hostname = hostname; +} + +inline const char *netif_hostname() { + return globals::netif_default.hostname; +} + +inline uint32_t netif_secondary_ipaddr() { + return globals::netif_default.secondary_ip.addr; +} + +inline uint32_t netif_broadcast_ipaddr() { + return globals::netif_default.broadcast_ip.addr; +} + +inline const uint8_t *netif_hwaddr() { + return globals::netif_default.hwaddr; +} +void netif_init(); +void netif_set_ipaddr(const ip4_addr_t ipaddr); +void netif_set_netmask(const ip4_addr_t netmask); +void netif_set_gw(const ip4_addr_t gw); +void netif_set_addr(const ip4_addr_t ipaddr, const ip4_addr_t netmask, const ip4_addr_t gw); + +void netif_add_ext_callback(netif_ext_callback_fn fn); + +/** + * Link + */ + +void netif_set_link_up(); +void netif_set_link_down(); + +inline bool netif_is_link_up() { + return (globals::netif_default.flags & netif::NETIF_FLAG_LINK_UP) == netif::NETIF_FLAG_LINK_UP; +} +} // namespace net + +#endif /* NETIF_H_ */ diff --git a/lib-network/include/network.h b/lib-network/include/network.h index da33407..7fe09f4 100644 --- a/lib-network/include/network.h +++ b/lib-network/include/network.h @@ -2,7 +2,7 @@ * @file network.h * */ -/* Copyright (C) 2017-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,117 +28,25 @@ #include -#define IP2STR(addr) (addr & 0xFF), ((addr >> 8) & 0xFF), ((addr >> 16) & 0xFF), ((addr >> 24) & 0xFF) -#define IPSTR "%d.%d.%d.%d" - -#define MAC2STR(mac) static_cast(mac[0]),static_cast(mac[1]),static_cast(mac[2]),static_cast(mac[3]), static_cast(mac[4]), static_cast(mac[5]) -#define MACSTR "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" +#include "ip4_address.h" namespace network { -static constexpr auto STORE = 96; ///< Configuration store in bytes -static constexpr auto IP_SIZE = 4U; -static constexpr auto MAC_SIZE = 6U; -static constexpr auto HOSTNAME_SIZE = 64U; ///< Including a terminating null byte. -static constexpr auto DOMAINNAME_SIZE = 64U; ///< Including a terminating null byte. -static constexpr auto IP4_BROADCAST = 0xffffffff; namespace dhcp { enum class Mode: uint8_t { INACTIVE = 0x00, ///< The IP address was not obtained via DHCP ACTIVE = 0x01, ///< The IP address was obtained via DHCP UNKNOWN = 0x02 ///< The system cannot determine if the address was obtained via DHCP }; -enum class ClientStatus { - IDLE, RENEW, GOT_IP, RETRYING, FAILED -}; } // namespace dhcp - -static constexpr uint32_t convert_to_uint(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) { - return static_cast(a) | - static_cast(b) << 8 | - static_cast(c) << 16 | - static_cast(d) << 24; -} - -inline bool is_netmask_valid(uint32_t nNetMask) { - if (nNetMask == 0) { - return false; - } - nNetMask = __builtin_bswap32(nNetMask); - return !(nNetMask & (~nNetMask >> 1)); - -} -/** - * The private address ranges are defined in RFC1918. - */ -inline bool is_private_ip(const uint32_t nIp) { - const uint8_t n = (nIp >> 8) & 0xFF; - - switch (nIp & 0xFF) { - case 10: - return true; - break; - case 172: - return (n >= 16) && (n < 32); - case 192: - return n == 168; - default: - break; - } - - return false; -} - -inline bool is_multicast_ip(const uint32_t nIp) { - if ((nIp & 0xE0) != 0xE0) { - return false; - } - - if ((nIp & 0xFFFFEF) == 0x0000E0) { // 224.0.0.0 to 224.0.0.255 Local subnetwork - return false; - } - - if ((nIp & 0xFFFFEF) == 0x0100E0) { // 224.0.1.0 to 224.0.1.255 Internetwork control - return false; - } - - return true; -} - -inline uint32_t cidr_to_netmask(const uint8_t nCIDR) { - if (nCIDR != 0) { - const auto nNetmask = __builtin_bswap32(static_cast(~0x0) << (32 - nCIDR)); - return nNetmask; - } - - return 0; -} - -void display_emac_config(); -void display_emac_start(); -void display_emac_status(const bool isLinkUp); -void display_ip(); -void display_netmask(); -void display_gateway(); -void display_hostname(); -void display_dhcp_status(network::dhcp::ClientStatus nStatus); -void display_emac_shutdown(); - -void mdns_announcement(); -void mdns_shutdown(); } // namespace network -class NetworkStore { -public: - virtual ~NetworkStore() {} - - virtual void SaveIp(uint32_t nIp)=0; - virtual void SaveNetMask(uint32_t nNetMask)=0; - virtual void SaveGatewayIp(uint32_t nGatewayIp)=0; - virtual void SaveHostName(const char *pHostName, uint32_t nLength)=0; - virtual void SaveDhcp(bool bIsDhcpUsed)=0; -}; - -#if defined (BARE_METAL) +#if defined(__linux__) || defined (__APPLE__) +# if defined (CONFIG_NETWORK_USE_MINIMUM) +# include "linux/minimum/network.h" +# else +# include "linux/network.h" +# endif +#else # if defined (ESP8266) # include "esp8266/network.h" # elif defined (NO_EMAC) @@ -146,8 +54,6 @@ class NetworkStore { # else # include "emac/network.h" # endif -#else -# include "linux/network.h" #endif #endif /* NETWORK_H_ */ diff --git a/lib-network/include/networkconst.h b/lib-network/include/networkconst.h index 4809ea1..185d103 100644 --- a/lib-network/include/networkconst.h +++ b/lib-network/include/networkconst.h @@ -2,7 +2,7 @@ * @file networkconst.h * */ -/* Copyright (C) 2019-2022 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2019-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib-network/include/networkparams.h b/lib-network/include/networkparams.h index 33bc2d6..33008df 100644 --- a/lib-network/include/networkparams.h +++ b/lib-network/include/networkparams.h @@ -2,7 +2,7 @@ * @file networkparams.h * */ -/* Copyright (C) 2017-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,12 +29,12 @@ #include #include "network.h" +#include "configstore.h" namespace networkparams { namespace defaults { static constexpr auto IS_DHCP_USED = true; static constexpr auto DHCP_RETRY_TIME = 0; -static constexpr auto NTP_UTC_OFFSET = 0.0f; } // namespace defaults struct Params { @@ -55,7 +55,7 @@ struct Params { }__attribute__((packed)); #if !defined (ESP8266) - static_assert(sizeof(struct Params) <= 96, "struct Params is too large"); + static_assert(sizeof(struct Params) <= network::STORE, "struct Params is too large"); #endif struct Mask { @@ -80,23 +80,26 @@ struct Mask { class NetworkParamsStore { public: - virtual ~NetworkParamsStore() {} + static void Update(const struct networkparams::Params *pParams) { + ConfigStore::Get()->Update(configstore::Store::NETWORK, pParams, sizeof(struct networkparams::Params)); + } - virtual void Update(const struct networkparams::Params *pNetworkParams)=0; - virtual void Copy(struct networkparams::Params *pNetworkParams)=0; + static void Copy(struct networkparams::Params *pParams) { + ConfigStore::Get()->Copy(configstore::Store::NETWORK, pParams, sizeof(struct networkparams::Params)); + } }; class NetworkParams { public: - NetworkParams(NetworkParamsStore *pNetworkParamsStore = nullptr); + NetworkParams(); - bool Load(); + void Load(); void Load(const char *pBuffer, uint32_t nLength); - void Builder(const struct networkparams::Params *ptNetworkParams, char *pBuffer, uint32_t nLength, uint32_t& nSize); - void Save(char *pBuffer, uint32_t nLength, uint32_t& nSize); - - void Dump(); + void Builder(const networkparams::Params *pParams, char *pBuffer, uint32_t nLength, uint32_t& nSize); + void Save(char *pBuffer, uint32_t nLength, uint32_t& nSize) { + Builder(nullptr, pBuffer, nLength, nSize); + } bool isDhcpUsed() const { return m_Params.bIsDhcpUsed; @@ -154,13 +157,13 @@ class NetworkParams { static void staticCallbackFunction(void *p, const char *s); private: + void Dump(); void callbackFunction(const char *s); bool isMaskSet(uint32_t nMask) const { return (m_Params.nSetList & nMask) == nMask; } private: - NetworkParamsStore *m_pNetworkParamsStore; networkparams::Params m_Params; }; diff --git a/lib-network/include/networkparamsconst.h b/lib-network/include/networkparamsconst.h index 93aef88..a5af867 100644 --- a/lib-network/include/networkparamsconst.h +++ b/lib-network/include/networkparamsconst.h @@ -2,7 +2,7 @@ * @file networkparamsconst.h * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,7 +38,6 @@ struct NetworkParamsConst { static const char HOSTNAME[]; static const char NTP_SERVER[]; - static const char NTP_UTC_OFFSET[]; #if defined (ESP8266) static const char NAME_SERVER[]; diff --git a/lib-network/include/networkstore.h b/lib-network/include/networkstore.h new file mode 100755 index 0000000..26fe06c --- /dev/null +++ b/lib-network/include/networkstore.h @@ -0,0 +1,60 @@ +/** + * @file networkstore.h + * + */ +/* Copyright (C) 2023 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef NETWORKSTORE_H_ +#define NETWORKSTORE_H_ + +#include +#include +#include + +#include "networkparams.h" +#include "configstore.h" + +class NetworkStore { +public: + static void SaveIp(uint32_t nIp) { + ConfigStore::Get()->Update(configstore::Store::NETWORK, offsetof(struct networkparams::Params, nLocalIp), &nIp, sizeof(uint32_t), networkparams::Mask::IP_ADDRESS); + } + + static void SaveNetMask(uint32_t nNetMask) { + ConfigStore::Get()->Update(configstore::Store::NETWORK, offsetof(struct networkparams::Params, nNetmask), &nNetMask, sizeof(uint32_t), networkparams::Mask::NET_MASK); + } + + static void SaveGatewayIp(uint32_t nGatewayIp) { + ConfigStore::Get()->Update(configstore::Store::NETWORK, offsetof(struct networkparams::Params, nGatewayIp), &nGatewayIp, sizeof(uint32_t), networkparams::Mask::DEFAULT_GATEWAY); + } + + static void SaveHostName(const char *pHostName, uint32_t nLength) { + nLength = std::min(nLength,static_cast(network::HOSTNAME_SIZE)); + ConfigStore::Get()->Update(configstore::Store::NETWORK, offsetof(struct networkparams::Params, aHostName), pHostName, nLength, networkparams::Mask::HOSTNAME); + } + + static void SaveDhcp(bool bIsDhcpUsed) { + ConfigStore::Get()->Update(configstore::Store::NETWORK, offsetof(struct networkparams::Params, bIsDhcpUsed), &bIsDhcpUsed, sizeof(bool), networkparams::Mask::DHCP); + } +}; + +#endif /* NETWORKSTORE_H_ */ diff --git a/lib-network/include/ntpclient.h b/lib-network/include/ntpclient.h deleted file mode 100644 index 375d222..0000000 --- a/lib-network/include/ntpclient.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file ntpclient.h - * - */ -/* Copyright (C) 2019-2021 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef NTPCLIENT_H_ -#define NTPCLIENT_H_ - -#include -#include - -#include "ntp.h" - -namespace ntpclient { -enum class Status { - IDLE, FAILED, STOPPED, WAITING -}; -} // namespace ntpclient - -struct NtpClientDisplay { - virtual ~NtpClientDisplay() {} - - virtual void ShowNtpClientStatus(ntpclient::Status nStatus)=0; -}; - - -class NtpClient { -public: - NtpClient(uint32_t nServerIp = 0); - - void Start(); - void Stop(); - void Run(); - - void Print(); - - ntpclient::Status GetStatus() { - return m_tStatus; - } - - void SetNtpClientDisplay(NtpClientDisplay *pNtpClientDisplay) { - m_pNtpClientDisplay = pNtpClientDisplay; - } - - static NtpClient *Get() { - return s_pThis; - } - -private: - void SetUtcOffset(float fUtcOffset); - void GetTimeNtpFormat(uint32_t &nSeconds, uint32_t &nFraction); - void Send(); - bool Receive(); - - struct TimeStamp { - uint32_t nSeconds; - uint32_t nFraction; - }; - - void Difference(const struct TimeStamp *Start, const struct TimeStamp *Stop, int32_t &nDiffSeconds, uint32_t &nDiffFraction); - int SetTimeOfDay(); - - void PrintNtpTime(const char *pText, const struct TimeStamp *pNtpTime); - -private: - uint32_t m_nServerIp; - int32_t m_nUtcOffset; - int32_t m_nHandle { -1 }; - ntpclient::Status m_tStatus { ntpclient::Status::IDLE }; - struct TNtpPacket m_Request; - struct TNtpPacket m_Reply; - uint32_t m_MillisRequest { 0 }; - uint32_t m_MillisLastPoll { 0 }; - - struct TimeStamp T1 { 0, 0 }; // time request sent by client - struct TimeStamp T2 { 0, 0 }; // time request received by server - struct TimeStamp T3 { 0, 0 }; // time reply sent by server - struct TimeStamp T4 { 0, 0 }; // time reply received by client - - int32_t m_nOffsetSeconds { 0 }; - uint32_t m_nOffsetMicros { 0 }; - - NtpClientDisplay *m_pNtpClientDisplay = nullptr; - - static NtpClient *s_pThis; -}; - -#endif /* NTPCLIENT_H_ */ diff --git a/lib-network/src/emac/gd32/emac.cpp b/lib-network/src/emac/gd32/emac.cpp index 811fedf..e482d33 100644 --- a/lib-network/src/emac/gd32/emac.cpp +++ b/lib-network/src/emac/gd32/emac.cpp @@ -2,7 +2,7 @@ * emac.cpp * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,117 +30,23 @@ #include "emac/phy.h" +#include "hwclock.h" + #include "debug.h" -extern enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; +extern "C" { +void console_error(const char *); +} +extern void enet_gpio_config(); +extern enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; extern void mac_address_get(uint8_t paddr[]); -static void enet_gpio_config(void) { - DEBUG_ENTRY -#if defined (GD32F10X) || defined (GD32F20X) - rcu_periph_clock_enable(RCU_GPIOA); - rcu_periph_clock_enable(RCU_GPIOB); - rcu_periph_clock_enable(RCU_GPIOC); - rcu_periph_clock_enable(RCU_AF); - - gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); - - rcu_pll2_config(RCU_PLL2_MUL10); - rcu_osci_on(RCU_PLL2_CK); - rcu_osci_stab_wait(RCU_PLL2_CK); - /* get 50MHz from CK_PLL2 on CKOUT0 pin (PA8) to clock the PHY */ -# if defined (GD32F10X_CL) - rcu_ckout0_config(RCU_CKOUT0SRC_CKPLL2); -# else - rcu_ckout0_config(RCU_CKOUT0SRC_CKPLL2,RCU_CKOUT0_DIV1); -# endif - gpio_ethernet_phy_select(GPIO_ENET_PHY_RMII); - - /* PA1: ETH_RMII_REF_CLK */ - gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_1); - /* PA2: ETH_MDIO */ - gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); - /* PA7: ETH_RMII_CRS_DV */ - gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_7); - - /* PC1: ETH_MDC */ - gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1); - /* PC4: ETH_RMII_RXD0 */ - gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4); - /* PC5: ETH_RMII_RXD1 */ - gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_5); - - /* PB11: ETH_RMII_TX_EN */ - gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11); - /* PB12: ETH_RMII_TXD0 */ - gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); - /* PB13: ETH_RMII_TXD1 */ - gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); -#else - rcu_periph_clock_enable(RCU_GPIOA); - rcu_periph_clock_enable(RCU_GPIOB); - rcu_periph_clock_enable(RCU_GPIOC); - rcu_periph_clock_enable(RCU_SYSCFG); - - gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_8); - gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); - gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_8); - - /* choose DIV4 to get 50MHz from 200MHz on CKOUT0 pin (PA8) to clock the PHY */ - rcu_ckout0_config(RCU_CKOUT0SRC_PLLP, RCU_CKOUT0_DIV4); - syscfg_enet_phy_interface_config(SYSCFG_ENET_PHY_RMII); - - /* PA1: ETH_RMII_REF_CLK */ - gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); - gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_1); - - /* PA2: ETH_MDIO */ - gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); - gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_2); - - /* PA7: ETH_RMII_CRS_DV */ - gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); - gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_7); - - gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_1); - gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_2); - gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_7); - - /* PB11: ETH_RMII_TX_EN */ - gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); - gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_11); - - /* PB12: ETH_RMII_TXD0 */ - gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); - gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_13); - - /* PB13: ETH_RMII_TXD1 */ - gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); - gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_14); - - gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_11); - gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_12); - gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_13); - - /* PC1: ETH_MDC */ - gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); - gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_1); - - /* PC4: ETH_RMII_RXD0 */ - gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); - gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_4); - - /* PC5: ETH_RMII_RXD1 */ - gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); - gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_200MHZ,GPIO_PIN_5); - - gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_1); - gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_4); - gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_5); +#if defined (CONFIG_ENET_ENABLE_PTP) +# include "gd32_ptp.h" +enet_descriptors_struct ptp_rxdesc_tab[ENET_RXBUF_NUM] __attribute__((aligned(4))); +enet_descriptors_struct ptp_txdesc_tab[ENET_TXBUF_NUM] __attribute__((aligned(4))); #endif - DEBUG_EXIT -} /* * Public function @@ -164,30 +70,40 @@ void __attribute__((cold)) emac_config() { rcu_periph_clock_enable(RCU_ENETTX); rcu_periph_clock_enable(RCU_ENETRX); - enet_deinit(); - enet_software_reset(); + enet_deinit(ENETx); + enet_software_reset(ENETx); - net::phy_config(PHY_ADDRESS); + if(!net::phy_config(PHY_ADDRESS)) { + console_error("net::phy_config(PHY_ADDRESS)"); + } DEBUG_EXIT } -void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) { +void emac_adjust_link(const net::PhyStatus phyStatus) { DEBUG_ENTRY - DEBUG_PRINTF("ENET_RXBUF_NUM=%u, ENET_TXBUF_NUM=%u", ENET_RXBUF_NUM, ENET_TXBUF_NUM); - net::PhyStatus phyStatus; - net::phy_start(PHY_ADDRESS, phyStatus); - - link = phyStatus.link; + printf("Link %s, %d, %s\n", + phyStatus.link == net::Link::STATE_UP ? "Up" : "Down", + phyStatus.speed == net::Speed::SPEED10 ? 10 : 100, + phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL"); #ifndef NDEBUG { uint16_t phy_value; +#if defined (GD32H7XX) + ErrStatus phy_state = enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value); +#else ErrStatus phy_state = enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value); +#endif printf("BCR: %.4x %s\n", phy_value, phy_state == SUCCESS ? "SUCCES" : "ERROR" ); +#if defined (GD32H7XX) + enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_state = enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); +#else enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); phy_state = enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); +#endif printf("BSR: %.4x %s\n", phy_value & (PHY_AUTONEGO_COMPLETE | PHY_LINKED_STATUS | PHY_JABBER_DETECTION), phy_state == SUCCESS ? "SUCCES" : "ERROR" ); } #endif @@ -204,12 +120,11 @@ void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) { mediamode = ENET_10M_FULLDUPLEX; } - printf("Link %s, %d, %s\n", - phyStatus.link == net::Link::STATE_UP ? "Up" : "Down", - phyStatus.speed == net::Speed::SPEED10 ? 10 : 100, - phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL"); - +#if defined (GD32H7XX) + const auto enet_init_status = enet_init(ENETx, mediamode, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_CUSTOM); +#else const auto enet_init_status = enet_init(mediamode, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_CUSTOM); +#endif if (enet_init_status != SUCCESS) {} @@ -218,26 +133,71 @@ void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) { #ifndef NDEBUG { uint16_t phy_value; +#if defined (GD32H7XX) + ErrStatus phy_state = enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value); +#else ErrStatus phy_state = enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value); +#endif printf("BCR: %.4x %s\n", phy_value, phy_state == SUCCESS ? "SUCCES" : "ERROR" ); +#if defined (GD32H7XX) + enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_state = enet_phy_write_read(ENETx, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); +#else enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); phy_state = enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); +#endif printf("BSR: %.4x %s\n", phy_value & (PHY_AUTONEGO_COMPLETE | PHY_LINKED_STATUS | PHY_JABBER_DETECTION), phy_state == SUCCESS ? "SUCCES" : "ERROR" ); } #endif + DEBUG_EXIT +} + +void __attribute__((cold)) emac_start(uint8_t mac_address[], net::Link& link) { + DEBUG_ENTRY + DEBUG_PRINTF("ENET_RXBUF_NUM=%u, ENET_TXBUF_NUM=%u", ENET_RXBUF_NUM, ENET_TXBUF_NUM); + + net::PhyStatus phyStatus; + net::phy_start(PHY_ADDRESS, phyStatus); + + link = phyStatus.link; + + emac_adjust_link(phyStatus); mac_address_get(mac_address); +#if defined (GD32H7XX) + enet_mac_address_set(ENETx, ENET_MAC_ADDRESS0, mac_address); +# if defined (CONFIG_ENET_ENABLE_PTP) + enet_ptp_normal_descriptors_chain_init(ENETx, ENET_DMA_TX, ptp_txdesc_tab); + enet_ptp_normal_descriptors_chain_init(ENETx, ENET_DMA_RX, ptp_rxdesc_tab); +# else + enet_descriptors_chain_init(ENETx, ENET_DMA_TX); + enet_descriptors_chain_init(ENETx, ENET_DMA_RX); +# endif +#else enet_mac_address_set(ENET_MAC_ADDRESS0, mac_address); - +# if defined (CONFIG_ENET_ENABLE_PTP) + enet_ptp_normal_descriptors_chain_init(ENET_DMA_TX, ptp_txdesc_tab); + enet_ptp_normal_descriptors_chain_init(ENET_DMA_RX, ptp_rxdesc_tab); +# else enet_descriptors_chain_init(ENET_DMA_TX); enet_descriptors_chain_init(ENET_DMA_RX); +# endif +#endif - for (unsigned i = 0; i < ENET_TXBUF_NUM; i++) { + for (uint32_t i = 0; i < ENET_TXBUF_NUM; i++) { enet_transmit_checksum_config(&txdesc_tab[i], ENET_CHECKSUM_TCPUDPICMP_FULL); } - enet_enable(); +#if defined (CONFIG_ENET_ENABLE_PTP) + gd32_ptp_start(); +# if !defined(DISABLE_RTC) + // Set the System Clock from the Hardware Clock + HwClock::Get()->HcToSys(); +# endif +#endif + + enet_enable(ENETx); DEBUG_EXIT } diff --git a/lib-network/src/emac/gd32/f/emac.cpp b/lib-network/src/emac/gd32/f/emac.cpp new file mode 100644 index 0000000..b33bf4b --- /dev/null +++ b/lib-network/src/emac/gd32/f/emac.cpp @@ -0,0 +1,144 @@ +/** + * emac.cpp + * + */ +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "gd32.h" + +#include "debug.h" + +/** + * Needed for older GD32F firmware + */ +#if !defined(GPIO_OSPEED_MAX) +# define GPIO_OSPEED_MAX GPIO_OSPEED_200MHZ +#endif + +void enet_gpio_config() { + DEBUG_ENTRY +#if defined (GD32F10X) || defined (GD32F20X) + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_AF); + + gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); + + rcu_pll2_config(RCU_PLL2_MUL10); + rcu_osci_on(RCU_PLL2_CK); + rcu_osci_stab_wait(RCU_PLL2_CK); + /* get 50MHz from CK_PLL2 on CKOUT0 pin (PA8) to clock the PHY */ +# if defined (GD32F10X_CL) + rcu_ckout0_config(RCU_CKOUT0SRC_CKPLL2); +# else + rcu_ckout0_config(RCU_CKOUT0SRC_CKPLL2,RCU_CKOUT0_DIV1); +# endif + gpio_ethernet_phy_select(GPIO_ENET_PHY_RMII); + + /* PA1: ETH_RMII_REF_CLK */ + gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_1); + /* PA2: ETH_MDIO */ + gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); + /* PA7: ETH_RMII_CRS_DV */ + gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_7); + + /* PC1: ETH_MDC */ + gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1); + /* PC4: ETH_RMII_RXD0 */ + gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4); + /* PC5: ETH_RMII_RXD1 */ + gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_5); + + /* PB11: ETH_RMII_TX_EN */ + gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11); + /* PB12: ETH_RMII_TXD0 */ + gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); + /* PB13: ETH_RMII_TXD1 */ + gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); +#else + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_GPIOB); + rcu_periph_clock_enable(RCU_GPIOC); + rcu_periph_clock_enable(RCU_SYSCFG); + + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_8); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_8); + + /* choose DIV4 to get 50MHz from 200MHz on CKOUT0 pin (PA8) to clock the PHY */ + rcu_ckout0_config(RCU_CKOUT0SRC_PLLP, RCU_CKOUT0_DIV4); + syscfg_enet_phy_interface_config(SYSCFG_ENET_PHY_RMII); + + /* PA1: ETH_RMII_REF_CLK */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_1); + + /* PA2: ETH_MDIO */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_2); + + /* PA7: ETH_RMII_CRS_DV */ + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_7); + + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_1); + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_2); + gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_7); + + /* PB11: ETH_RMII_TX_EN */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_11); + + /* PB12: ETH_RMII_TXD0 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_13); + + /* PB13: ETH_RMII_TXD1 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_14); + + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_11); + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_12); + gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_13); + + /* PC1: ETH_MDC */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_1); + + /* PC4: ETH_RMII_RXD0 */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_4); + + /* PC5: ETH_RMII_RXD1 */ + gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); + gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_MAX,GPIO_PIN_5); + + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_1); + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_4); + gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_5); +#endif + DEBUG_EXIT +} diff --git a/lib-network/src/emac/gd32/f/net.cpp b/lib-network/src/emac/gd32/f/net.cpp new file mode 100644 index 0000000..713d281 --- /dev/null +++ b/lib-network/src/emac/gd32/f/net.cpp @@ -0,0 +1,244 @@ +/** + * net.cpp + * + */ +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + +#include +#include + +#include "gd32.h" +#include "../src/net/net_memcpy.h" + +#include "debug.h" + +#if defined (CONFIG_ENET_ENABLE_PTP) +#include "gd32_ptp.h" + +extern enet_descriptors_struct *dma_current_ptp_rxdesc; +extern enet_descriptors_struct *dma_current_ptp_txdesc; +namespace net { +namespace globals { +extern uint32_t ptpTimestamp[2]; +} // namespace globals +} // namespace net +#endif +extern enet_descriptors_struct *dma_current_rxdesc; +extern enet_descriptors_struct *dma_current_txdesc; + +int emac_eth_recv(uint8_t **ppPacket) { + const auto nLength = enet_desc_information_get(dma_current_rxdesc, RXDESC_FRAME_LENGTH); + + if (nLength > 0) { +#if defined (CONFIG_ENET_ENABLE_PTP) + *ppPacket = reinterpret_cast(dma_current_ptp_rxdesc->buffer1_addr); +#else + *ppPacket = reinterpret_cast(dma_current_rxdesc->buffer1_addr); +#endif + return nLength; + } + + return -1; +} + +#if defined (CONFIG_ENET_ENABLE_PTP) +static void ptpframe_receive_normal_mode() { + net::globals::ptpTimestamp[0] = dma_current_rxdesc->buffer1_addr; + net::globals::ptpTimestamp[1] = dma_current_rxdesc->buffer2_next_desc_addr; + + dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc->buffer1_addr; + dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc->buffer2_next_desc_addr; + dma_current_rxdesc->status = ENET_RDES0_DAV; + + if (0 != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0U; + } + + assert(0 != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)); + + dma_current_rxdesc = reinterpret_cast(dma_current_ptp_rxdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if (0 != dma_current_ptp_rxdesc->status) { + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_rxdesc = reinterpret_cast(dma_current_ptp_rxdesc->status); + } else { + /* ponter to the next ptp descriptor */ + dma_current_ptp_rxdesc++; + } +} +#else +static void frame_receive() { + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if (0 != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0U; + } + + assert(0 != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)); + + dma_current_rxdesc = reinterpret_cast(dma_current_rxdesc->buffer2_next_desc_addr); +} +#endif + +void emac_free_pkt() { + while(0 != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + __DMB(); + } +#if defined (CONFIG_ENET_ENABLE_PTP) + ptpframe_receive_normal_mode(); +#else + frame_receive(); +#endif +} + +#if defined (CONFIG_ENET_ENABLE_PTP) +inline static void ptpframe_transmit(const uint8_t *pBuffer, const uint32_t nLength, const bool bCaptureTimestamp) { + assert (nullptr != pBuffer); + assert(nLength <= ENET_MAX_FRAME_SIZE); + + auto *pDst = reinterpret_cast(dma_current_ptp_txdesc->buffer1_addr); + net::memcpy(pDst, pBuffer, nLength); + + dma_current_txdesc->control_buffer_size = (nLength & (uint32_t)0x1FFF); + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + const auto dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + const auto dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if ((0 != dma_tbu_flag) || (0 != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0U; + } + + uint32_t timeout = 0; + uint32_t tdes0_ttmss_flag; + + if (bCaptureTimestamp) { + do { + tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); + __DMB(); + timeout++; + } while((0 == tdes0_ttmss_flag) && (timeout < UINT32_MAX)); + + DEBUG_PRINTF("timeout=%x %d", timeout, (dma_current_txdesc->status & ENET_TDES0_TTMSS)); + + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + + net::globals::ptpTimestamp[0] = dma_current_txdesc->buffer1_addr; + net::globals::ptpTimestamp[1] = dma_current_txdesc->buffer2_next_desc_addr; + } + + dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc->buffer1_addr; + dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc->buffer2_next_desc_addr; + + assert(0 != (dma_current_txdesc->status & ENET_TDES0_TCHM)); /* chained mode */ + + /* update the current TxDMA descriptor pointer to the next descriptor in TxDMA descriptor table */ + dma_current_txdesc = reinterpret_cast(dma_current_ptp_txdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0 != dma_current_ptp_txdesc->status) { + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_txdesc = reinterpret_cast(dma_current_ptp_txdesc->status); + } else { + /* pointer to the next ptp descriptor */ + dma_current_ptp_txdesc++; + } +} + +void emac_eth_send(void *pBuffer, uint32_t nLength) { + while (0 != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + __DMB(); + } + + auto nStatus = dma_current_txdesc->status; + nStatus &= ~ENET_TDES0_TTSEN; + dma_current_txdesc->status = nStatus; + + ptpframe_transmit(reinterpret_cast(pBuffer), nLength, false); +} + +void emac_eth_send_timestamp(void *pBuffer, uint32_t nLength) { + while (0 != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + __DMB(); + } + + auto nStatus = dma_current_txdesc->status; + nStatus |= ENET_TDES0_TTSEN; + dma_current_txdesc->status = nStatus; + + ptpframe_transmit(reinterpret_cast(pBuffer), nLength, true); +} +#else +void emac_eth_send(void *pBuffer, uint32_t nLength) { + assert(nullptr != pBuffer); + assert(nLength <= static_cast(ENET_MAX_FRAME_SIZE)); + + while (0 != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + __DMB(); + } + + auto *pDst = reinterpret_cast(dma_current_txdesc->buffer1_addr); + net::memcpy(pDst, pBuffer, nLength); + + /* set the frame length */ + dma_current_txdesc->control_buffer_size = nLength; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + const auto dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU); + const auto dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if ((0 != dma_tbu_flag) || (0 != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0; + } + + assert(0 != (dma_current_txdesc->status & ENET_TDES0_TCHM)); /* chained mode */ + + /* update the current TxDMA descriptor pointer to the next descriptor in TxDMA descriptor table*/ + dma_current_txdesc = reinterpret_cast(dma_current_txdesc->buffer2_next_desc_addr); +} +#endif diff --git a/lib-network/src/emac/gd32/net_link_check.cpp b/lib-network/src/emac/gd32/net_link_check.cpp index 1571107..f3efe05 100644 --- a/lib-network/src/emac/gd32/net_link_check.cpp +++ b/lib-network/src/emac/gd32/net_link_check.cpp @@ -25,6 +25,7 @@ #include +#include "emac/phy.h" #include "emac/net_link_check.h" #include "gd32.h" diff --git a/lib-network/src/emac/gd32/net_phy.cpp b/lib-network/src/emac/gd32/net_phy.cpp index 018729a..693aa29 100644 --- a/lib-network/src/emac/gd32/net_phy.cpp +++ b/lib-network/src/emac/gd32/net_phy.cpp @@ -2,7 +2,7 @@ * net_phy.cpp * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,22 +28,28 @@ #include "emac/phy.h" #include "emac/mmi.h" +#include "hardware.h" #include "gd32.h" #include "debug.h" -extern volatile uint32_t s_nSysTickMillis; - namespace net { - bool phy_read(uint32_t nAddress, const uint32_t nRegister, uint16_t &nValue) { +#if defined (GD32H7XX) + const auto bResult = enet_phy_write_read(ENETx, ENET_PHY_READ, nAddress, nRegister, &nValue) == SUCCESS; +#else const auto bResult = enet_phy_write_read(ENET_PHY_READ, nAddress, nRegister, &nValue) == SUCCESS; +#endif // DEBUG_PRINTF("%d %.2x %.2x %.4x", bResult, nAddress, nRegister, nValue); return bResult; } bool phy_write(uint32_t nAddress, const uint32_t nRegister, uint16_t nValue) { +#if defined (GD32H7XX) + const auto bResult = enet_phy_write_read(ENETx, ENET_PHY_WRITE, nAddress, nRegister, &nValue) == SUCCESS; +#else const auto bResult = enet_phy_write_read(ENET_PHY_WRITE, nAddress, nRegister, &nValue) == SUCCESS; +#endif // DEBUG_PRINTF("%d %.2x %.2x %.4x", bResult, nAddress, nRegister, nValue); return bResult; } @@ -51,11 +57,17 @@ bool phy_write(uint32_t nAddress, const uint32_t nRegister, uint16_t nValue) { bool phy_config(const uint32_t nAddress) { DEBUG_ENTRY +#if defined (GD32H7XX) + uint32_t reg = ENET_MAC_PHY_CTL(ENETx); +#else uint32_t reg = ENET_MAC_PHY_CTL; +#endif reg &= ~ENET_MAC_PHY_CTL_CLR; const uint32_t ahbclk = rcu_clock_freq_get(CK_AHB); + DEBUG_PRINTF("ahbclk=%u", ahbclk); + #if defined GD32F10X_CL if (ENET_RANGE(ahbclk, 20000000U, 35000000U)) { reg |= ENET_MDC_HCLK_DIV16; @@ -89,14 +101,38 @@ bool phy_config(const uint32_t nAddress) { reg |= ENET_MDC_HCLK_DIV42; } else if (ENET_RANGE(ahbclk, 100000000U, 150000000U)) { reg |= ENET_MDC_HCLK_DIV62; - } else if ((ENET_RANGE(ahbclk, 150000000U, 200000000U)) || (200000000U == ahbclk)) { + } else if ((ENET_RANGE(ahbclk, 150000000U, 240000000U)) || (240000000U == ahbclk)) { reg |= ENET_MDC_HCLK_DIV102; } else { return false; } +#elif defined GD32H7XX + if (ENET_RANGE(ahbclk, 20000000U, 35000000U)) { + reg |= ENET_MDC_HCLK_DIV16; + } else if (ENET_RANGE(ahbclk, 35000000U, 60000000U)) { + reg |= ENET_MDC_HCLK_DIV26; + } else if (ENET_RANGE(ahbclk, 60000000U, 100000000U)) { + reg |= ENET_MDC_HCLK_DIV42; + } else if (ENET_RANGE(ahbclk, 100000000U, 150000000U)) { + reg |= ENET_MDC_HCLK_DIV62; + } else if ((ENET_RANGE(ahbclk, 150000000U, 180000000U)) || (180000000U == ahbclk)) { + reg |= ENET_MDC_HCLK_DIV102; + } else if (ENET_RANGE(ahbclk, 250000000U, 300000000U)) { + reg |= ENET_MDC_HCLK_DIV124; + } else if (ENET_RANGE(ahbclk, 300000000U, 350000000U)) { + reg |= ENET_MDC_HCLK_DIV142; + } else if ((ENET_RANGE(ahbclk, 350000000U, 400000000U)) || (400000000U == ahbclk)) { + reg |= ENET_MDC_HCLK_DIV162; + } else { + return false; + } #endif +#if defined (GD32H7XX) + ENET_MAC_PHY_CTL(ENETx) = reg; +#else ENET_MAC_PHY_CTL = reg; +#endif if (!phy_write(nAddress, mmi::REG_BMCR, mmi::BMCR_RESET)) { DEBUG_PUTS("PHY reset failed"); @@ -109,17 +145,17 @@ bool phy_config(const uint32_t nAddress) { * IEEE spec. */ - const auto nMillis = s_nSysTickMillis; + const auto nMillis = Hardware::Get()->Millis(); uint16_t nValue; - while (s_nSysTickMillis - nMillis < 500) { + while (Hardware::Get()->Millis() - nMillis < 500) { if (!phy_read(nAddress, mmi::REG_BMCR, nValue)) { DEBUG_PUTS("PHY status read failed"); return false; } if (!(nValue & mmi::BMCR_RESET)) { - DEBUG_PRINTF("%u", s_nSysTickMillis - nMillis); + DEBUG_PRINTF("%u", Hardware::Get()->Millis() - nMillis); DEBUG_EXIT return true; } @@ -130,7 +166,7 @@ bool phy_config(const uint32_t nAddress) { return false; } - DEBUG_PRINTF("%u", s_nSysTickMillis - nMillis); + DEBUG_PRINTF("%u", Hardware::Get()->Millis() - nMillis); DEBUG_EXIT return true; } diff --git a/lib-network/src/emac/network.cpp b/lib-network/src/emac/network.cpp index 8ad248a..e993f43 100755 --- a/lib-network/src/emac/network.cpp +++ b/lib-network/src/emac/network.cpp @@ -2,7 +2,7 @@ * network.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,29 +23,37 @@ * THE SOFTWARE. */ +#ifdef DEBUG_NETWORK +# undef NDEBUG +#endif + #include +#include #include #include #include #include "network.h" #include "networkparams.h" +#include "networkstore.h" #include "hardware.h" -#include "../net/net.h" -#include "../../config/net_config.h" - #include "emac/emac.h" #include "emac/phy.h" #include "emac/mmi.h" #include "emac/net_link_check.h" +#include "netif.h" +#include "net/autoip.h" +#include "net/dhcp.h" + +#include "../../config/net_config.h" + #include "debug.h" namespace network { void __attribute__((weak)) mdns_announcement() {} -void __attribute__((weak)) mdns_shutdown() {} } // namespace network static constexpr char TO_HEX(const char i) { @@ -56,42 +64,71 @@ static constexpr char TO_HEX(const char i) { # define PHY_ADDRESS 1 #endif +static void netif_ext_callback(const uint16_t reason, [[maybe_unused]] const net::netif_ext_callback_args_t *args) { + DEBUG_ENTRY + + if ((reason & net::NetifReason::NSC_IPV4_ADDRESS_CHANGED) == net::NetifReason::NSC_IPV4_ADDRESS_CHANGED) { + net::display_ip(); + network::mdns_announcement(); + + printf("ip: " IPSTR " -> " IPSTR "\n", IP2STR(args->ipv4_changed.old_address.addr), IP2STR(net::netif_ipaddr())); + } + + if ((reason & net::NetifReason::NSC_IPV4_NETMASK_CHANGED) == net::NetifReason::NSC_IPV4_NETMASK_CHANGED) { + net::display_netmask(); + + printf("netmask: " IPSTR " -> " IPSTR "\n", IP2STR(args->ipv4_changed.old_netmask.addr), IP2STR(net::netif_netmask())); + } + + if ((reason & net::NetifReason::NSC_IPV4_GATEWAY_CHANGED) == net::NetifReason::NSC_IPV4_GATEWAY_CHANGED) { + net::display_gateway(); + + printf("gw: " IPSTR " -> " IPSTR "\n", IP2STR(args->ipv4_changed.old_gw.addr), IP2STR(net::netif_gw())); + } + + if ((reason & net::NetifReason::NSC_LINK_CHANGED) == net::NetifReason::NSC_LINK_CHANGED) { + if (args->link_changed.state == 0) { // Link down + net::net_link_down(); + + DEBUG_EXIT + return; + } + } + + DEBUG_EXIT +} + Network *Network::s_pThis; -Network::Network(NetworkParamsStore *pNetworkParamsStore) { +Network::Network() { DEBUG_ENTRY assert(s_pThis == nullptr); s_pThis = this; - m_aDomainName[0] = '\0'; - strcpy(m_aIfName, "eth0"); + m_aDomainName[0] = '\0'; + memset(&m_nNameservers, 0, sizeof(m_nNameservers)); - network::display_emac_config(); + net::display_emac_config(); emac_config(); - network::display_emac_start(); - - emac_start(m_aNetMacaddr, s_lastState); - - NetworkParams params(pNetworkParamsStore); - - if (params.Load()) { - params.Dump(); - } + net::display_emac_start(); - m_IpInfo.ip.addr = params.GetIpAddress(); - m_IpInfo.netmask.addr = params.GetNetMask(); - m_IpInfo.gw.addr = params.GetDefaultGateway(); - m_IsDhcpUsed = params.isDhcpUsed(); - m_nNtpServerIp = params.GetNtpServer(); - m_fNtpUtcOffset = params.GetNtpUtcOffset(); + emac_start(net::globals::netif_default.hwaddr, s_lastState); + printf(MACSTR "\n", MAC2STR(net::globals::netif_default.hwaddr)); net::phy_customized_timing(); net::phy_customized_led(); + net::netif_init(); + net::netif_add_ext_callback(netif_ext_callback); + + NetworkParams params; + params.Load(); + const auto *p = params.GetHostName(); + assert(p != nullptr); if (*p == '\0') { uint32_t k = 0; @@ -100,18 +137,35 @@ Network::Network(NetworkParamsStore *pNetworkParamsStore) { m_aHostName[k++] = HOST_NAME_PREFIX[i]; } - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[3] >> 4); - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[3] & 0x0F); - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[4] >> 4); - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[4] & 0x0F); - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[5] >> 4); - m_aHostName[k++] = TO_HEX(m_aNetMacaddr[5] & 0x0F); + auto hwaddr = net::globals::netif_default.hwaddr; + + m_aHostName[k++] = TO_HEX(hwaddr[3] >> 4); + m_aHostName[k++] = TO_HEX(hwaddr[3] & 0x0F); + m_aHostName[k++] = TO_HEX(hwaddr[4] >> 4); + m_aHostName[k++] = TO_HEX(hwaddr[4] & 0x0F); + m_aHostName[k++] = TO_HEX(hwaddr[5] >> 4); + m_aHostName[k++] = TO_HEX(hwaddr[5] & 0x0F); m_aHostName[k] = '\0'; } else { strncpy(m_aHostName, p, sizeof(m_aHostName) - 1); m_aHostName[sizeof(m_aHostName) - 1] = '\0'; } + net::netif_set_hostname(m_aHostName); + + net::ip4_addr_t ipaddr; + net::ip4_addr_t netmask; + net::ip4_addr_t gw; + + ipaddr.addr = params.GetIpAddress(); + netmask.addr = params.GetNetMask(); + gw.addr = params.GetDefaultGateway(); + + bool isDhcpUsed = params.isDhcpUsed(); + + net::display_emac_status(net::Link::STATE_UP == s_lastState); + net::net_init(s_lastState, ipaddr, netmask, gw, isDhcpUsed); + #if defined (ENET_LINK_CHECK_USE_INT) net::link_interrupt_init(); #elif defined (ENET_LINK_CHECK_USE_PIN_POLL) @@ -119,110 +173,23 @@ Network::Network(NetworkParamsStore *pNetworkParamsStore) { #elif defined (ENET_LINK_CHECK_REG_POLL) net::link_status_read(); #endif - - network::display_emac_status(net::Link::STATE_UP == s_lastState); - - if (net::Link::STATE_UP == s_lastState) { - DEBUG_PUTS("net::Link::STATE_UP"); - - if (!m_IsDhcpUsed) { - DEBUG_PUTS(""); - if (m_IpInfo.ip.addr == 0) { - DEBUG_PUTS(""); - } else if (!IsValidIp(m_IpInfo.gw.addr)) { - DEBUG_PUTS(""); - m_IpInfo.gw.addr = m_IpInfo.ip.addr; - } - } - - if (m_IsDhcpUsed) { - network::display_dhcp_status(network::dhcp::ClientStatus::RENEW); - } - - net_init(m_aNetMacaddr, &m_IpInfo, m_aHostName, &m_IsDhcpUsed, &m_IsZeroconfUsed); - - if (m_IsZeroconfUsed) { - network::display_dhcp_status(network::dhcp::ClientStatus::FAILED); - } - - const auto nRetryTime = params.GetDhcpRetryTime(); - const auto bUseDhcp = params.isDhcpUsed(); - - while (m_IsZeroconfUsed && (nRetryTime != 0) && bUseDhcp) { - Hardware::Get()->SetMode(hardware::ledblink::Mode::FAST); - - network::display_dhcp_status(network::dhcp::ClientStatus::RETRYING); - - DEBUG_PUTS(""); - auto nTime = time(nullptr); - while ((time(nullptr) - nTime) < (nRetryTime * 60)) { - Hardware::Get()->Run(); - } - - network::display_dhcp_status(network::dhcp::ClientStatus::RENEW); - - Hardware::Get()->SetMode(hardware::ledblink::Mode::OFF_ON); - - m_IsDhcpUsed = true; - m_IsZeroconfUsed = false; - - net_init(m_aNetMacaddr, &m_IpInfo, m_aHostName, &m_IsDhcpUsed, &m_IsZeroconfUsed); - - if (m_IsDhcpUsed) { - break; - } - } - } else { - DEBUG_PUTS("net::Link::STATE_DOWN"); - - if (m_IsDhcpUsed) { - DEBUG_PUTS("m_IsDhcpUsed=true"); - m_IpInfo.ip.addr = 0; - m_IpInfo.netmask.addr = 0; - m_IpInfo.gw.addr = 0; - } - - auto bFalse = false; - - net_init(m_aNetMacaddr, &m_IpInfo, m_aHostName, &bFalse, &bFalse); - } - - network::display_ip(); - network::display_netmask(); - network::display_gateway(); - DEBUG_EXIT } void Network::SetIp(uint32_t nIp) { DEBUG_ENTRY - if (m_IsDhcpUsed) { - m_IsDhcpUsed = false; - net_dhcp_release(); - } - - m_IsZeroconfUsed = false; - - m_IpInfo.ip.addr = nIp; - - if (nIp == 0) { - } else { - m_IpInfo.gw.addr = m_IpInfo.ip.addr; + if (nIp == net::netif_ipaddr()) { + DEBUG_EXIT + return; } - net_set_ip(&m_IpInfo); - net_set_gw(&m_IpInfo); - - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveIp(m_IpInfo.ip.addr); - m_pNetworkStore->SaveGatewayIp(m_IpInfo.gw.addr); - m_pNetworkStore->SaveDhcp(false); - } + net::ip4_addr_t ipaddr; + ipaddr.addr = nIp; + net_set_primary_ip(ipaddr); - network::mdns_announcement(); - network::display_ip(); - network::display_netmask(); + NetworkStore::SaveIp(nIp); + NetworkStore::SaveDhcp(false); DEBUG_EXIT } @@ -230,20 +197,17 @@ void Network::SetIp(uint32_t nIp) { void Network::SetNetmask(uint32_t nNetmask) { DEBUG_ENTRY - if (m_IpInfo.netmask.addr == nNetmask) { + if (nNetmask == net::netif_netmask()) { DEBUG_EXIT return; } - m_IpInfo.netmask.addr = nNetmask; - net_set_netmask(&m_IpInfo); + net::ip4_addr_t netmask; + netmask.addr = nNetmask; - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveNetMask(m_IpInfo.netmask.addr); - } + net::netif_set_netmask(netmask); - network::display_ip(); - network::display_netmask(); + NetworkStore::SaveNetMask(nNetmask); DEBUG_EXIT } @@ -251,19 +215,17 @@ void Network::SetNetmask(uint32_t nNetmask) { void Network::SetGatewayIp(uint32_t nGatewayIp) { DEBUG_ENTRY - if (m_IpInfo.gw.addr == nGatewayIp) { + if (nGatewayIp == net::netif_gw()) { DEBUG_EXIT return; } - m_IpInfo.gw.addr = nGatewayIp; - net_set_gw(&m_IpInfo); + net::ip4_addr_t gw; + gw.addr = nGatewayIp; - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveGatewayIp(m_IpInfo.gw.addr); - } + net::netif_set_gw(gw); - network::display_gateway(); + NetworkStore::SaveGatewayIp(nGatewayIp); DEBUG_EXIT } @@ -274,145 +236,126 @@ void Network::SetHostName(const char *pHostName) { strncpy(m_aHostName, pHostName, network::HOSTNAME_SIZE - 1); m_aHostName[network::HOSTNAME_SIZE - 1] = '\0'; - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveHostName(m_aHostName, static_cast(strlen(m_aHostName))); - } + NetworkStore::SaveHostName(m_aHostName, static_cast(strlen(m_aHostName))); network::mdns_announcement(); - network::display_hostname(); + net::display_hostname(); DEBUG_EXIT } -bool Network::SetZeroconf() { +void Network::SetZeroconf() { DEBUG_ENTRY - const auto bWatchdog = Hardware::Get()->IsWatchdog(); - - if (bWatchdog) { - Hardware::Get()->WatchdogStop(); - } - - m_IsZeroconfUsed = net_set_zeroconf(&m_IpInfo); - - if (m_IsZeroconfUsed) { - m_IsDhcpUsed = false; - - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveDhcp(true);// Zeroconf is enabled only when use_dhcp=1 - } - } - - network::mdns_announcement(); - network::display_ip(); - network::display_netmask(); + net::autoip_start(); - if (bWatchdog) { - Hardware::Get()->WatchdogInit(); - } + NetworkStore::SaveDhcp(false); DEBUG_EXIT - return m_IsZeroconfUsed; } -bool Network::EnableDhcp() { +void Network::EnableDhcp() { DEBUG_ENTRY - const auto bWatchdog = Hardware::Get()->IsWatchdog(); - - if (bWatchdog) { - Hardware::Get()->WatchdogStop(); - } - - network::display_dhcp_status(network::dhcp::ClientStatus::RENEW); + net::dhcp_start(); - m_IsDhcpUsed = net_set_dhcp(&m_IpInfo, m_aHostName, &m_IsZeroconfUsed); - - if (m_IsZeroconfUsed) { - network::display_dhcp_status(network::dhcp::ClientStatus::FAILED); - } else { - network::display_dhcp_status(network::dhcp::ClientStatus::GOT_IP); - } - - DEBUG_PRINTF("m_IsDhcpUsed=%d, m_IsZeroconfUsed=%d", m_IsDhcpUsed, m_IsZeroconfUsed); - - if (m_pNetworkStore != nullptr) { - m_pNetworkStore->SaveDhcp(m_IsDhcpUsed); - } - - network::mdns_announcement(); - network::display_ip(); - network::display_netmask(); - network::display_gateway(); - - if (bWatchdog) { - Hardware::Get()->WatchdogInit(); - } + NetworkStore::SaveDhcp(true); DEBUG_EXIT - return m_IsDhcpUsed; } -void Network::SetQueuedStaticIp(uint32_t nLocalIp, uint32_t nNetmask) { +void Network::SetQueuedStaticIp(const uint32_t nStaticIp, const uint32_t nNetmask) { DEBUG_ENTRY - DEBUG_PRINTF(IPSTR ", nNetmask=" IPSTR, IP2STR(nLocalIp), IP2STR(nNetmask)); + DEBUG_PRINTF(IPSTR ", nNetmask=" IPSTR, IP2STR(nStaticIp), IP2STR(nNetmask)); - if (nLocalIp != 0) { - m_QueuedConfig.nLocalIp = nLocalIp; + if (nStaticIp != 0) { + m_QueuedConfig.nStaticIp = nStaticIp; + } else { + m_QueuedConfig.nStaticIp = GetIp(); } if (nNetmask != 0) { m_QueuedConfig.nNetmask = nNetmask; + } else { + m_QueuedConfig.nNetmask = GetNetmask(); } m_QueuedConfig.nMask |= QueuedConfig::STATIC_IP; - m_QueuedConfig.nMask |= QueuedConfig::NET_MASK; + m_QueuedConfig.nMask |= QueuedConfig::NETMASK; DEBUG_EXIT } +void Network::SetQueuedDefaultRoute(const uint32_t nGatewayIp) { + if (nGatewayIp != 0) { + m_QueuedConfig.nGateway = nGatewayIp; + } else { + m_QueuedConfig.nGateway = GetGatewayIp(); + } + + m_QueuedConfig.nMask |= QueuedConfig::GW; +} + bool Network::ApplyQueuedConfig() { DEBUG_ENTRY - DEBUG_PRINTF("m_QueuedConfig.nMask=%x, " IPSTR ", " IPSTR, m_QueuedConfig.nMask, IP2STR(m_QueuedConfig.nLocalIp), IP2STR(m_QueuedConfig.nNetmask)); + DEBUG_PRINTF("m_QueuedConfig.nMask=%x, " IPSTR ", " IPSTR, m_QueuedConfig.nMask, IP2STR(m_QueuedConfig.nStaticIp), IP2STR(m_QueuedConfig.nNetmask)); if (m_QueuedConfig.nMask == QueuedConfig::NONE) { DEBUG_EXIT return false; } - if ((isQueuedMaskSet(QueuedConfig::STATIC_IP)) || (isQueuedMaskSet(QueuedConfig::NET_MASK))) { - if (isQueuedMaskSet(QueuedConfig::NET_MASK)) { + if ((isQueuedMaskSet(QueuedConfig::STATIC_IP)) || (isQueuedMaskSet(QueuedConfig::NETMASK)) || (isQueuedMaskSet(QueuedConfig::GW))) { + // After SetIp all ip address might be zero. + if (isQueuedMaskSet(QueuedConfig::STATIC_IP)) { + SetIp(m_QueuedConfig.nStaticIp); + } + + if (isQueuedMaskSet(QueuedConfig::NETMASK)) { SetNetmask(m_QueuedConfig.nNetmask); - m_QueuedConfig.nMask &= ~(QueuedConfig::NET_MASK); } - if (isQueuedMaskSet(QueuedConfig::STATIC_IP)) { - SetIp(m_QueuedConfig.nLocalIp); - m_QueuedConfig.nMask &= ~(QueuedConfig::STATIC_IP); + if (isQueuedMaskSet(QueuedConfig::GW)) { + SetGatewayIp(m_QueuedConfig.nGateway); } + + m_QueuedConfig.nMask = QueuedConfig::NONE; + + DEBUG_EXIT + return true; } if (isQueuedMaskSet(QueuedConfig::DHCP)) { - EnableDhcp(); - m_QueuedConfig.nMask &= ~(QueuedConfig::DHCP); + if (m_QueuedConfig.mode == network::dhcp::Mode::ACTIVE) { + EnableDhcp(); + } else if (m_QueuedConfig.mode == network::dhcp::Mode::INACTIVE) { + + } + + m_QueuedConfig.mode = network::dhcp::Mode::UNKNOWN; + m_QueuedConfig.nMask = QueuedConfig::NONE; + + DEBUG_EXIT + return true; } if (isQueuedMaskSet(QueuedConfig::ZEROCONF)) { SetZeroconf(); - m_QueuedConfig.nMask &= ~(QueuedConfig::ZEROCONF); + m_QueuedConfig.nMask = QueuedConfig::NONE; + + DEBUG_EXIT + return true; } DEBUG_EXIT - return true; + return false; } -#include - void Network::Print() { printf("Network [%c]\n", GetAddressingMode()); printf(" Hostname : %s\n", m_aHostName); - printf(" IfName : %d: %s " MACSTR "\n", m_nIfIndex, m_aIfName, MAC2STR(m_aNetMacaddr)); - printf(" Primary : " IPSTR "/%d (HTTP only " IPSTR ")\n", IP2STR(m_IpInfo.ip.addr), GetNetmaskCIDR(), IP2STR(m_IpInfo.secondary_ip.addr)); - printf(" Gateway : " IPSTR "\n", IP2STR(m_IpInfo.gw.addr)); + printf(" IfName : %u: %s " MACSTR "\n", static_cast(GetIfIndex()), m_aIfName, MAC2STR(net::netif_hwaddr())); + printf(" Primary : " IPSTR "/%u (HTTP only " IPSTR ")\n", IP2STR(net::netif_ipaddr()), static_cast(GetNetmaskCIDR()), IP2STR(net::netif_secondary_ipaddr())); + printf(" Gateway : " IPSTR "\n", IP2STR(net::netif_gw())); printf(" Broadcast : " IPSTR "\n", IP2STR(GetBroadcastIp())); } diff --git a/lib-network/src/emac/phy/json_get_phystatus.cpp b/lib-network/src/emac/phy/json_get_phystatus.cpp index 73fa4ee..ace4991 100755 --- a/lib-network/src/emac/phy/json_get_phystatus.cpp +++ b/lib-network/src/emac/phy/json_get_phystatus.cpp @@ -29,11 +29,11 @@ namespace remoteconfig { namespace net { -uint16_t json_get_phystatus(char *pOutBuffer, const uint16_t nOutBufferSize) { +uint32_t json_get_phystatus(char *pOutBuffer, const uint32_t nOutBufferSize) { ::net::PhyStatus phyStatus; ::net::phy_customized_status(phyStatus); - const auto nLength = static_cast(snprintf(pOutBuffer, nOutBufferSize, + const auto nLength = static_cast(snprintf(pOutBuffer, nOutBufferSize, "{\"link\":\"%s\",\"speed\":\"%s\",\"duplex\":\"%s\",\"autonegotiation\":\"%s\"}", ::net::phy_string_get_link(phyStatus.link), ::net::phy_string_get_speed(phyStatus.speed), diff --git a/lib-network/src/emac/phy/link_handle_change.cpp b/lib-network/src/emac/phy/link_handle_change.cpp old mode 100644 new mode 100755 index 5b86f3a..44bd517 --- a/lib-network/src/emac/phy/link_handle_change.cpp +++ b/lib-network/src/emac/phy/link_handle_change.cpp @@ -2,7 +2,7 @@ * link_handle_change.cpp * */ -/* Copyright (C) 2022 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,23 +23,41 @@ * THE SOFTWARE. */ +#include "hardware.h" #include "network.h" +#include "netif.h" #include "debug.h" -/** - * Default implementation - */ +#if !defined(PHY_ADDRESS) +# define PHY_ADDRESS 1 +#endif + +extern void emac_adjust_link(const net::PhyStatus); namespace net { -void __attribute__((weak)) link_handle_change(const net::Link state) { +void link_handle_change(const net::Link state) { DEBUG_PRINTF("net::Link %s", state == net::Link::STATE_UP ? "UP" : "DOWN"); - if (net::Link::STATE_UP == state) { - if (Network::Get()->IsDhcpUsed()) { - DEBUG_PUTS("Enable DHCP"); - Network::Get()->EnableDhcp(); + if (Link::STATE_UP == state) { + const bool isWatchdog = Hardware::Get()->IsWatchdog(); + if (isWatchdog) { + Hardware::Get()->WatchdogStop(); } + + PhyStatus phyStatus; + phy_start(PHY_ADDRESS, phyStatus); + + emac_adjust_link(phyStatus); + + if (isWatchdog) { + Hardware::Get()->WatchdogInit(); + } + + netif_set_link_up(); + return; } + + netif_set_link_down(); } } // namespace net diff --git a/lib-network/src/emac/phy/net_link_check.cpp b/lib-network/src/emac/phy/net_link_check.cpp old mode 100644 new mode 100755 index c266780..ddacbd9 --- a/lib-network/src/emac/phy/net_link_check.cpp +++ b/lib-network/src/emac/phy/net_link_check.cpp @@ -2,7 +2,7 @@ * net_link_check.cpp * */ -/* Copyright (C) 2022-2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2022-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,13 +48,6 @@ void link_pin_poll_init() { #endif net::Link link_status_read() { - uint16_t nValue = 0; - phy_read(PHY_ADDRESS, mmi::REG_BMSR, nValue); - - if (mmi::BMSR_LINKED_STATUS == (nValue & mmi::BMSR_LINKED_STATUS)) { - return net::Link::STATE_UP; - } - - return net::Link::STATE_DOWN; + return net::phy_get_link(PHY_ADDRESS); } } // namespace net diff --git a/lib-network/src/emac/phy/net_phy.cpp b/lib-network/src/emac/phy/net_phy.cpp index 61be500..8219018 100755 --- a/lib-network/src/emac/phy/net_phy.cpp +++ b/lib-network/src/emac/phy/net_phy.cpp @@ -2,7 +2,7 @@ * net_phy.cpp * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,10 +33,11 @@ #include "hardware.h" #include "debug.h" -namespace net { - -static PhyStatus s_phyStatus; +#if !defined(PHY_ADDRESS) +# define PHY_ADDRESS 1 +#endif +namespace net { bool phy_get_id(const uint32_t nAddress, PhyIdentifier& phyIdentifier) { DEBUG_ENTRY DEBUG_PRINTF("nAddress=%.2x", nAddress); @@ -64,6 +65,17 @@ bool phy_get_id(const uint32_t nAddress, PhyIdentifier& phyIdentifier) { return true; } +Link phy_get_link(const uint32_t nAddress) { + uint16_t nValue = 0; + phy_read(nAddress, mmi::REG_BMSR, nValue); + + if (mmi::BMSR_LINKED_STATUS == (nValue & mmi::BMSR_LINKED_STATUS)) { + return net::Link::STATE_UP; + } + + return net::Link::STATE_DOWN; +} + bool phy_powerdown(const uint32_t nAddress) { return phy_write(nAddress, mmi::REG_BMCR, mmi::BMCR_POWERDOWN); } @@ -163,7 +175,7 @@ static bool phy_config_autonegotiation(const uint32_t nAddress, const uint16_t n * @param nAddress PHY address * @return true for success, false for failure */ -static bool phy_update_link(const uint32_t nAddress) { +static bool phy_update_link(const uint32_t nAddress, PhyStatus& phyStatus) { DEBUG_ENTRY uint16_t nBMSR; @@ -178,7 +190,7 @@ static bool phy_update_link(const uint32_t nAddress) { * we don't need to wait for autoneg again */ - if ((s_phyStatus.link == Link::STATE_DOWN) && (nBMSR & mmi::BMSR_LINKED_STATUS)) { + if ((phyStatus.link == Link::STATE_DOWN) && (nBMSR & mmi::BMSR_LINKED_STATUS)) { DEBUG_EXIT return true; } @@ -195,14 +207,14 @@ static bool phy_update_link(const uint32_t nAddress) { phy_read(nAddress, mmi::REG_BMSR, nBMSR); } - s_phyStatus.link = Link::STATE_UP; + phyStatus.link = Link::STATE_UP; DEBUG_PRINTF("%u", Hardware::Get()->Millis() - nMillis); DEBUG_EXIT return true; } else { phy_read(nAddress, mmi::REG_BMSR, nBMSR); - s_phyStatus.link = nBMSR & mmi::BMSR_LINKED_STATUS ? Link::STATE_UP : Link::STATE_DOWN; + phyStatus.link = nBMSR & mmi::BMSR_LINKED_STATUS ? Link::STATE_UP : Link::STATE_DOWN; DEBUG_EXIT return true; @@ -214,10 +226,10 @@ static bool phy_update_link(const uint32_t nAddress) { return true; } -static bool phy_parse_link(const uint32_t nAddress) { +static void phy_parse_link(const uint32_t nAddress, PhyStatus& phyStatus) { - s_phyStatus.duplex = Duplex::DUPLEX_HALF; - s_phyStatus.speed = Speed::SPEED10; + phyStatus.duplex = Duplex::DUPLEX_HALF; + phyStatus.speed = Speed::SPEED10; uint16_t nADVERTISE; phy_read(nAddress, mmi::REG_ADVERTISE, nADVERTISE); @@ -227,16 +239,14 @@ static bool phy_parse_link(const uint32_t nAddress) { nLPA &= nADVERTISE; if (nLPA & (mmi::LPA_100FULL | mmi::LPA_100HALF)) { - s_phyStatus.speed = Speed::SPEED100; + phyStatus.speed = Speed::SPEED100; if (nLPA & mmi::LPA_100FULL) { - s_phyStatus.duplex = Duplex::DUPLEX_FULL; + phyStatus.duplex = Duplex::DUPLEX_FULL; } } else if (nLPA & mmi::LPA_10FULL) { - s_phyStatus.duplex = Duplex::DUPLEX_FULL; + phyStatus.duplex = Duplex::DUPLEX_FULL; } - - return true; } bool phy_start(const uint32_t nAddress, PhyStatus& phyStatus) { @@ -249,17 +259,19 @@ bool phy_start(const uint32_t nAddress, PhyStatus& phyStatus) { return false; } - if (!phy_update_link(nAddress)) { + if (!phy_update_link(nAddress, phyStatus)) { DEBUG_EXIT return false; } - if (!phy_parse_link(nAddress)) { - DEBUG_EXIT - return false; - } + phy_parse_link(nAddress, phyStatus); + + phyStatus.link = phy_get_link(nAddress); - phyStatus = s_phyStatus; + DEBUG_PRINTF("Link %s, %d, %s", + phyStatus.link == net::Link::STATE_UP ? "Up" : "Down", + phyStatus.speed == net::Speed::SPEED10 ? 10 : 100, + phyStatus.duplex == net::Duplex::DUPLEX_HALF ? "HALF" : "FULL"); DEBUG_EXIT return true; diff --git a/lib-network/src/emac/phy/phygen/net_phy.cpp b/lib-network/src/emac/phy/phygen/net_phy.cpp index 07b68f2..aeb63ab 100755 --- a/lib-network/src/emac/phy/phygen/net_phy.cpp +++ b/lib-network/src/emac/phy/phygen/net_phy.cpp @@ -53,16 +53,14 @@ void phy_customized_timing() { } void phy_customized_status(PhyStatus& phyStatus) { - phyStatus.link = link_status_read(); - uint16_t nValue; - phy_read(PHY_ADDRESS, mmi::REG_BMCR, nValue); + phy_read(PHY_ADDRESS, mmi::REG_BMSR, nValue); debug_print_bits(nValue); - phyStatus.duplex = ((nValue & BIT(8)) == BIT(8)) ? Duplex::DUPLEX_FULL : Duplex::DUPLEX_HALF; - phyStatus.speed = ((nValue & BIT(13)) == BIT(13)) ? Speed::SPEED100 : Speed::SPEED10; - phyStatus.bAutonegotiation = ((nValue & mmi::BMCR_AUTONEGOTIATION) == mmi::BMCR_AUTONEGOTIATION); - + phyStatus.duplex = Duplex::DUPLEX_FULL; + phyStatus.speed = Speed::SPEED100; + phyStatus.link = (nValue & mmi::BMSR_LINKED_STATUS) ? Link::STATE_UP : Link::STATE_DOWN; + phyStatus.bAutonegotiation = (nValue & mmi::BMSR_AUTONEGO_COMPLETE); } } // namespace net diff --git a/lib-network/src/emac/phy/rtl8201f/net_phy.cpp b/lib-network/src/emac/phy/rtl8201f/net_phy.cpp index f8c5433..3805005 100755 --- a/lib-network/src/emac/phy/rtl8201f/net_phy.cpp +++ b/lib-network/src/emac/phy/rtl8201f/net_phy.cpp @@ -2,7 +2,7 @@ * phy.cpp * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@gd32-dmx.org +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,9 +56,16 @@ void phy_write_paged(uint16_t phy_page, uint16_t phy_reg, uint16_t phy_value, ui DEBUG_PRINTF("tmp_value=0x%.4x, phy_value=0x%.4x", tmp_value, phy_value); phy_write(PHY_ADDRESS, phy_reg, tmp_value); + phy_write(PHY_ADDRESS, PHY_REG_PAGE_SELECT, 0); +} - phy_page = 0; +void phy_read_paged(const uint16_t phy_page, const uint16_t phy_reg, uint16_t& phy_value, const uint16_t mask = 0x0) { phy_write(PHY_ADDRESS, PHY_REG_PAGE_SELECT, phy_page); + + phy_read(PHY_ADDRESS, phy_reg, phy_value); + phy_value &= mask; + + phy_write(PHY_ADDRESS, PHY_REG_PAGE_SELECT, 0); } void phy_customized_led() { @@ -75,18 +82,26 @@ void phy_customized_led() { DEBUG_EXIT } +#define RMSR_RX_TIMING_SHIFT 4 +#define RMSR_RX_TIMING_MASK 0xF0 + +#define RMSR_TX_TIMING_SHIFT 8 +#define RMSR_TX_TIMING_MASK 0xF00 + void phy_customized_timing() { DEBUG_ENTRY -#if defined (GD32F407) || defined (GD32F450) -# define RMSR_RX_TIMING_SHIFT 4 -# define RMSR_RX_TIMING_MASK 0xF0 +#if defined (GD32F4XX) # define RMSR_RX_TIMING_VAL 0x4 -# define RMSR_TX_TIMING_SHIFT 8 -# define RMSR_TX_TIMING_MASK 0xF00 -# define RMSR_TX_TIMING_VAL 0xF +# if defined (GD32F407) +# define RMSR_TX_TIMING_VAL 0x2 // The GD32F407 is now running at 200MHz +# elif defined (GD32F470) +# define RMSR_TX_TIMING_VAL 0x1 +# else +# define RMSR_TX_TIMING_VAL 0xF +# endif constexpr uint16_t phy_value = (RMSR_RX_TIMING_VAL << RMSR_RX_TIMING_SHIFT) - | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT); + | (RMSR_TX_TIMING_VAL << RMSR_TX_TIMING_SHIFT); phy_write_paged(0x7, PHY_REG_RMSR, phy_value, RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK); #endif DEBUG_EXIT @@ -103,4 +118,24 @@ void phy_customized_status(PhyStatus& phyStatus) { phyStatus.bAutonegotiation = ((nValue & mmi::BMCR_AUTONEGOTIATION) == mmi::BMCR_AUTONEGOTIATION); } +namespace phy { +void rtl8201f_get_timings(uint32_t& nRxTiming, uint32_t& nTxTiming) { + uint16_t nValue; + phy_read_paged(0x7, PHY_REG_RMSR, nValue, RMSR_RX_TIMING_MASK | RMSR_TX_TIMING_MASK); + + nRxTiming = (nValue >> RMSR_RX_TIMING_SHIFT) & 0xF; + nTxTiming = (nValue >> RMSR_TX_TIMING_SHIFT) & 0xF; +} + +void rtl8201f_set_rxtiming(const uint32_t nRxTiming) { + const auto nValue = static_cast((nRxTiming & 0xF) << RMSR_RX_TIMING_SHIFT); + phy_write_paged(0x7, PHY_REG_RMSR, nValue, RMSR_RX_TIMING_MASK); +} + +void rtl8201f_set_txtiming(const uint32_t nTxTiming) { + const auto nValue = static_cast((nTxTiming & 0xF) << RMSR_TX_TIMING_SHIFT); + phy_write_paged(0x7, PHY_REG_RMSR, nValue, RMSR_TX_TIMING_MASK); +} + +} // namespace phy } // namespace net diff --git a/lib-network/src/net/acd.cpp b/lib-network/src/net/acd.cpp new file mode 100755 index 0000000..ea97ef6 --- /dev/null +++ b/lib-network/src/net/acd.cpp @@ -0,0 +1,328 @@ +/** + * @file acd.cpp + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* This code is inspired by the lwIP TCP/IP stack. + * https://savannah.nongnu.org/projects/lwip/ + */ +/** + * The acp.cpp aims to be conform to RFC 5227. + * https://datatracker.ietf.org/doc/html/rfc5227.html + * IPv4 Address Conflict Detection + */ + +#if defined (DEBUG_NET_ACD) +# undef NDEBUG +#endif + +#pragma GCC push_options +#pragma GCC optimize ("Os") + +#include +#include +#include +#include + +#include "../../config/net_config.h" + +#include "net/acd.h" +#include "net/protocol/acd.h" +#include "net/protocol/arp.h" +#include "net_memcpy.h" + +#include "hardware.h" +#include "debug.h" + +namespace net { +namespace acd { +static constexpr uint32_t ACD_TMR_INTERVAL = 100; +static constexpr uint32_t ACD_TICKS_PER_SECOND = (1000U / ACD_TMR_INTERVAL); +} // namespace acd + +static int32_t nTimerId; + +static void acd_timer() { + auto *acd = reinterpret_cast(globals::netif_default.acd); + assert(acd != nullptr); + + if (acd->lastconflict > 0) { + acd->lastconflict--; + } + + DEBUG_PRINTF("state=%u, ttw=%u", static_cast(acd->state), acd->ttw); + + if (acd->ttw > 0) { + acd->ttw--; + } + + switch (acd->state) { + case acd::State::ACD_STATE_PROBE_WAIT: + case acd::State::ACD_STATE_PROBING: + if (acd->ttw == 0) { + acd->state = acd::State::ACD_STATE_PROBING; + arp_acd_probe(acd->ipaddr); + DEBUG_PUTS("PROBING Sent Probe"); + acd->sent_num++; + if (acd->sent_num >= PROBE_NUM) { + acd->state = acd::State::ACD_STATE_ANNOUNCE_WAIT; + acd->sent_num = 0; + acd->ttw = static_cast(ANNOUNCE_WAIT * acd::ACD_TICKS_PER_SECOND); + } else { + acd->ttw = static_cast(random() % (((PROBE_MAX - PROBE_MIN) * acd::ACD_TICKS_PER_SECOND)) + (PROBE_MIN * acd::ACD_TICKS_PER_SECOND)); + } + } + break; + case acd::State::ACD_STATE_ANNOUNCE_WAIT: + case acd::State::ACD_STATE_ANNOUNCING: + if (acd->ttw == 0) { + if (acd->sent_num == 0) { + acd->state = acd::State::ACD_STATE_ANNOUNCING; + acd->num_conflicts = 0; + } + arp_acd_send_announcement(acd->ipaddr); + DEBUG_PUTS("ANNOUNCING Sent Announce"); + acd->ttw = static_cast(ANNOUNCE_INTERVAL * acd::ACD_TICKS_PER_SECOND); + acd->sent_num++; + + if (acd->sent_num >= ANNOUNCE_NUM) { + acd->state = acd::State::ACD_STATE_ONGOING; + acd->sent_num = 0; + acd->ttw = 0; + acd->acd_conflict_callback(acd::Callback::ACD_IP_OK); + } + } + break; + case acd::State::ACD_STATE_RATE_LIMIT: + if (acd->ttw == 0) { + acd_stop(acd); + acd->acd_conflict_callback(acd::Callback::ACD_RESTART_CLIENT); + } + break; + default: + break; + } +} + +static void acd_restart(struct acd::Acd *acd) { + acd->num_conflicts++; + acd->acd_conflict_callback(acd::Callback::ACD_DECLINE); + + if (acd->num_conflicts >= MAX_CONFLICTS) { + acd->state = acd::State::ACD_STATE_RATE_LIMIT; + acd->ttw = static_cast(RATE_LIMIT_INTERVAL * acd::ACD_TICKS_PER_SECOND); + DEBUG_PUTS("rate limiting initiated. too many conflicts"); + } + else { + acd_stop(acd); + acd->acd_conflict_callback(acd::Callback::ACD_RESTART_CLIENT); + } +} + +static void acd_handle_arp_conflict(struct acd::Acd *acd) { + /* RFC5227, 2.4 "Ongoing Address Conflict Detection and Address Defense" + allows three options where: + a) means retreat on the first conflict, + b) allows to keep an already configured address when having only one + conflict in DEFEND_INTERVAL seconds and + c) the host will not give up it's address and defend it indefinitely + + We use option b) when the acd module represents the netif address, since it + helps to improve the chance that one of the two conflicting hosts may be + able to retain its address. while we are flexible enough to help network + performance + + We use option a) when the acd module does not represent the netif address, + since we cannot have the acd module announcing or restarting. This + situation occurs for the LL acd module when a routable address is used on + the netif but the LL address is still open in the background. */ + + if (acd->state == acd::State::ACD_STATE_PASSIVE_ONGOING) { + DEBUG_PUTS("conflict when we are in passive mode -> back off"); + acd_stop(acd); + acd->acd_conflict_callback(acd::Callback::ACD_DECLINE); + } + else { + if (acd->lastconflict > 0) { + DEBUG_PUTS("conflict within DEFEND_INTERVAL -> retreating"); + acd_restart(acd); + } else { + DEBUG_PUTS("we are defending, send ARP Announce"); + arp_acd_send_announcement(acd->ipaddr); + acd->lastconflict = DEFEND_INTERVAL * acd::ACD_TICKS_PER_SECOND; + } + } +} + +static void acd_put_in_passive_mode() { + auto *acd = reinterpret_cast(globals::netif_default.acd); + assert(acd != nullptr); + + switch (acd->state) { + case acd::State::ACD_STATE_OFF: + case acd::State::ACD_STATE_PASSIVE_ONGOING: + default: + /* do nothing */ + break; + case acd::State::ACD_STATE_PROBE_WAIT: + case acd::State::ACD_STATE_PROBING: + case acd::State::ACD_STATE_ANNOUNCE_WAIT: + case acd::State::ACD_STATE_RATE_LIMIT: + acd_stop(acd); + acd->acd_conflict_callback(acd::Callback::ACD_DECLINE); + break; + case acd::State::ACD_STATE_ANNOUNCING: + case acd::State::ACD_STATE_ONGOING: + acd->state = acd::State::ACD_STATE_PASSIVE_ONGOING; + break; + } +} + +/* + * Public interface + */ + +void acd_start(struct acd::Acd *acd, const ip4_addr_t ipaddr) { + DEBUG_ENTRY + assert(acd != nullptr); + + acd->ipaddr.addr = ipaddr.addr; + acd->state = acd::State::ACD_STATE_PROBE_WAIT; + acd->ttw = static_cast(random() % (PROBE_WAIT * acd::ACD_TICKS_PER_SECOND)); + + nTimerId = Hardware::Get()->SoftwareTimerAdd(acd::ACD_TMR_INTERVAL, acd_timer); + assert(nTimerId >= 0); + + DEBUG_EXIT +} + +void acd_stop(struct acd::Acd *acd) { + DEBUG_ENTRY + assert(acd != nullptr); + + acd->state = acd::State::ACD_STATE_OFF; + + assert(nTimerId >= 0); + Hardware::Get()->SoftwareTimerDelete(nTimerId); + nTimerId = -1; + + DEBUG_EXIT +} + +void acd_network_changed_link_down() { + DEBUG_ENTRY + + auto *acd = reinterpret_cast(globals::netif_default.acd); + acd_stop(acd); + + DEBUG_EXIT +} + +void acd_arp_reply(struct t_arp *pArp) { + DEBUG_ENTRY + auto *acd = reinterpret_cast(globals::netif_default.acd); + + switch (acd->state) { + case acd::State::ACD_STATE_OFF: + case acd::State::ACD_STATE_RATE_LIMIT: + default: + break; + case acd::State::ACD_STATE_PROBE_WAIT: + case acd::State::ACD_STATE_PROBING: + case acd::State::ACD_STATE_ANNOUNCE_WAIT: + /* RFC 5227 Section 2.1.1: + * from beginning to after ANNOUNCE_WAIT seconds we have a conflict if + * ip.sender == ipaddr (someone is already using the address) + * OR + * ip.dst == ipaddr && hw.src != own macAddress (someone else is probing it) + */ + if (((memcpy_ip(pArp->arp.sender_ip) == acd->ipaddr.addr)) + || (!(memcpy_ip(pArp->arp.sender_ip) == 0) + && ((memcpy_ip(pArp->arp.target_ip)) == acd->ipaddr.addr) + && (memcmp(pArp->arp.sender_mac, globals::netif_default.hwaddr, ETH_ADDR_LEN) == 0))) + { + DEBUG_PUTS("Probe Conflict detected"); + acd_restart(acd); + } + break; + case acd::State::ACD_STATE_ANNOUNCING: + case acd::State::ACD_STATE_ONGOING: + case acd::State::ACD_STATE_PASSIVE_ONGOING: + /* RFC 5227 Section 2.4: + * in any state we have a conflict if + * ip.sender == ipaddr && hw.src != own macAddress (someone is using our address) + */ + if ((memcpy_ip(pArp->arp.sender_ip) == acd->ipaddr.addr) + && (memcmp(pArp->arp.sender_mac, globals::netif_default.hwaddr, ETH_ADDR_LEN) != 0)) { + DEBUG_PUTS("Conflicting ARP-Packet detected"); + acd_handle_arp_conflict(acd); + } + break; + } + + DEBUG_EXIT +} + +void acd_add(struct acd::Acd *pAcd, acd_conflict_callback_t acd_conflict_callback) { + DEBUG_ENTRY + assert(pAcd != nullptr); + assert(acd_conflict_callback != nullptr); + + pAcd->acd_conflict_callback = acd_conflict_callback; + + auto &netif = globals::netif_default; + netif.acd = pAcd; + + DEBUG_EXIT +} + +void acd_remove(struct acd::Acd *pAcd) { + DEBUG_ENTRY + + assert(pAcd != nullptr); + auto &netif = globals::netif_default; + + if (netif.acd == pAcd) { + netif.acd = nullptr; + + DEBUG_EXIT + return; + } + + DEBUG_EXIT +} + +void acd_netif_ip_addr_changed(const ip4_addr_t old_addr, const ip4_addr_t new_addr) { + if ((old_addr.addr == 0) || (new_addr.addr == 0)) { + return; + } + + auto *acd = reinterpret_cast(globals::netif_default.acd); + + if (acd->ipaddr.addr == old_addr.addr) { + /* Did we change from a LL address to a routable address? */ + if (network::is_linklocal_ip(old_addr.addr) && !network::is_linklocal_ip(new_addr.addr)) { + /* Put the module in passive conflict detection mode */ + acd_put_in_passive_mode(); + } + } +} +} // namespace net diff --git a/lib-network/src/apps/tftp/tftpdaemon.cpp b/lib-network/src/net/apps/tftp/tftpdaemon.cpp similarity index 96% rename from lib-network/src/apps/tftp/tftpdaemon.cpp rename to lib-network/src/net/apps/tftp/tftpdaemon.cpp index ca31123..3d0c3d9 100644 --- a/lib-network/src/apps/tftp/tftpdaemon.cpp +++ b/lib-network/src/net/apps/tftp/tftpdaemon.cpp @@ -2,7 +2,7 @@ * @file tftpdaemon.cpp * */ -/* Copyright (C) 2019-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2019-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,7 +31,7 @@ #include #include -#include "tftpdaemon.h" +#include "net/apps/tftpdaemon.h" #include "network.h" @@ -259,7 +259,7 @@ void TFTPDaemon::DoRead() { FileClose(); } - DEBUG_PRINTF("m_nDataLength=%ld, m_nPacketLength=%d, m_bIsLastBlock=%d", m_nDataLength, m_nPacketLength, m_bIsLastBlock); + DEBUG_PRINTF("m_nDataLength=%u, m_nPacketLength=%d, m_bIsLastBlock=%d", m_nDataLength, m_nPacketLength, m_bIsLastBlock); } DEBUG_PRINTF("Sending to " IPSTR ":%d", IP2STR(m_nFromIp), m_nFromPort); @@ -304,7 +304,7 @@ void TFTPDaemon::HandleRecvData() { m_nDataLength = m_nLength - 4; m_nBlockNumber = __builtin_bswap16(pDataPacket->BlockNumber); - DEBUG_PRINTF("Incoming from " IPSTR ", m_nLength=%u, m_nBlockNumber=%d, m_nDataLength=%u", IP2STR(m_nFromIp), static_cast(m_nLength), m_nBlockNumber, static_cast(m_nDataLength)); + DEBUG_PRINTF("Incoming from " IPSTR ", m_nLength=%u, m_nBlockNumber=%d, m_nDataLength=%u", IP2STR(m_nFromIp), m_nLength, m_nBlockNumber, m_nDataLength); if (m_nDataLength == FileWrite(pDataPacket->Data, m_nDataLength, m_nBlockNumber)) { diff --git a/lib-network/src/net/arp.cpp b/lib-network/src/net/arp.cpp old mode 100644 new mode 100755 index 1cb8e09..466e923 --- a/lib-network/src/net/arp.cpp +++ b/lib-network/src/net/arp.cpp @@ -2,7 +2,7 @@ * @file arp.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,228 +22,497 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +/** + * https://datatracker.ietf.org/doc/html/rfc826 + * An Ethernet Address Resolution Protocol + * -- or -- + * Converting Network Protocol Addresses + */ + +#if defined (DEBUG_NET_ARP) +# undef NDEBUG +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif #include #include +#include #include -#include "net.h" +#include "../../config/net_config.h" + +#include "net_memcpy.h" #include "net_private.h" -#include "../../config/net_config.h" +#include "net/arp.h" +#include "net/acd.h" +#include "net/protocol/arp.h" +#include "net/protocol/udp.h" +#include "netif.h" -namespace net { -namespace arp { -enum class RequestType { - REQUEST, - PROBE, - ANNNOUNCEMENT -}; -} // namespace arp -} // namespace net +#include "hardware.h" -static struct t_arp s_arp_request ALIGNED ; -static struct t_arp s_arp_reply ALIGNED; -static net::arp::RequestType s_requestType ALIGNED; -static bool s_isProbeReplyReceived ALIGNED; +#include "debug.h" + +#if !defined ARP_MAX_RECORDS +static constexpr auto MAX_RECORDS = 16; +#else +static constexpr auto MAX_RECORDS = ARP_MAX_RECORDS; +#endif namespace net { namespace globals { -extern struct IpInfo ipInfo; -extern uint8_t macAddress[ETH_ADDR_LEN]; +extern uint32_t nOnNetworkMask; } // namespace globals -} // namespace net -typedef union pcast32 { - uint32_t u32; - uint8_t u8[4]; -} _pcast32; +namespace arp { +static constexpr uint32_t TIMER_INTERVAL = 1000; ///< 1 second +static constexpr uint32_t MAX_PROBING = 2; ///< 2 * 1 second +static constexpr uint32_t MAX_REACHABLE = (10 * 60); ///< (10 * 60) * 1 second = 10 minutes +static constexpr uint32_t MAX_STALE = ( 5 * 60); ///< ( 5 * 60) * 1 second = 5 minutes -void __attribute__((cold)) arp_init() { - arp_cache_init(); +enum class State { + STATE_EMPTY, STATE_PROBE, STATE_REACHABLE, STATE_STALE, +}; - s_requestType = net::arp::RequestType::REQUEST; +struct Packet { + uint8_t *p; + uint32_t nSize; +#if defined CONFIG_ENET_ENABLE_PTP + bool isTimestamp; +#endif +}; - // ARP Request template - // Ethernet header - memcpy(s_arp_request.ether.src, net::globals::macAddress, ETH_ADDR_LEN); - memset(s_arp_request.ether.dst, 0xFF , ETH_ADDR_LEN); - s_arp_request.ether.type = __builtin_bswap16(ETHER_TYPE_ARP); +struct Record { + uint32_t nIp; + Packet packet; + uint8_t mac_address[ETH_ADDR_LEN]; + uint16_t nAge; + State state; +}; +} // namespace arp - // ARP Header - s_arp_request.arp.hardware_type = __builtin_bswap16(ARP_HWTYPE_ETHERNET); - s_arp_request.arp.protocol_type = __builtin_bswap16(ARP_PRTYPE_IPv4); - s_arp_request.arp.hardware_size = ARP_HARDWARE_SIZE; - s_arp_request.arp.protocol_size = ARP_PROTOCOL_SIZE; - s_arp_request.arp.opcode = __builtin_bswap16(ARP_OPCODE_RQST); +static net::arp::Record s_ArpRecords[MAX_RECORDS] SECTION_NETWORK ALIGNED; - memcpy(s_arp_request.arp.sender_mac, net::globals::macAddress, ETH_ADDR_LEN); - _pcast32 ip_addr; - ip_addr.u32 = net::globals::ipInfo.ip.addr; - memcpy(s_arp_request.arp.sender_ip, ip_addr.u8, IPv4_ADDR_LEN); - memset(s_arp_request.arp.target_mac, 0x00, ETH_ADDR_LEN); +static struct t_arp s_arp_request ALIGNED ; +static struct t_arp s_arp_reply ALIGNED; - // ARP Reply Template - // Ethernet header - memcpy(s_arp_reply.ether.src, net::globals::macAddress, ETH_ADDR_LEN); - s_arp_reply.ether.type = __builtin_bswap16(ETHER_TYPE_ARP); +#ifndef NDEBUG +static constexpr char STATE[4][12] = { "EMPTY", "PROBE", "REACHABLE", "STALE", }; - // ARP Header - s_arp_reply.arp.hardware_type = __builtin_bswap16(ARP_HWTYPE_ETHERNET); - s_arp_reply.arp.protocol_type = __builtin_bswap16(ARP_PRTYPE_IPv4); - s_arp_reply.arp.hardware_size = ARP_HARDWARE_SIZE; - s_arp_reply.arp.protocol_size = ARP_PROTOCOL_SIZE; - s_arp_reply.arp.opcode = __builtin_bswap16(ARP_OPCODE_REPLY); +void static arp_cache_record_dump(net::arp::Record *pRecord) { + printf("%p %-4d %c " MACSTR " %-10s " IPSTR "\n", pRecord, pRecord->nAge, pRecord->packet.p == nullptr ? '-' : 'Q' , MAC2STR(pRecord->mac_address), STATE[static_cast(pRecord->state)], IP2STR(pRecord->nIp)); +} - memcpy(s_arp_reply.arp.sender_mac, net::globals::macAddress, ETH_ADDR_LEN); +void static arp_cache_dump() { + uint32_t nIndex = 0; + for (auto &record : s_ArpRecords) { + printf("%p %02d %-4d" MACSTR " %-10s " IPSTR "\n", &record, nIndex++, record.nAge, MAC2STR(record.mac_address), STATE[static_cast(record.state)], IP2STR(record.nIp)); + if (nIndex ==6) { + return; + } + } } +#else +void static arp_cache_record_dump([[maybe_unused]] net::arp::Record *pRecord) {} +void static arp_cache_dump() {} +#endif -bool arp_do_probe() { - int32_t nTimeout; - auto nRetries = 3; +static net::arp::Record *arp_find_record(const uint32_t nDestinationIp, [[maybe_unused]] const arp::Flags flag) { + DEBUG_ENTRY - while (nRetries--) { - arp_send_probe(); + net::arp::Record *pStale = nullptr; + net::arp::Record *pReachable = nullptr; + uint32_t nAgeStale = 0; + uint32_t nAgeReachable = 0; - nTimeout = 0x1FFFF; -#ifndef NDEBUG - nTimeout+= 0x40000; -#endif + for (auto &record : s_ArpRecords) { + if (record.nIp == nDestinationIp) { + DEBUG_EXIT + return &record; + } + + if (flag == arp::Flags::FLAG_UPDATE) { + continue; + } - while ((nTimeout-- > 0) && !s_isProbeReplyReceived) { - net_handle(); + if (record.state == net::arp::State::STATE_EMPTY) { + record.nIp = nDestinationIp; + DEBUG_EXIT + return &record; } - if (s_isProbeReplyReceived) { - return true; + if (record.state == net::arp::State::STATE_REACHABLE) { + if (record.nAge > nAgeReachable) { + nAgeReachable = record.nAge; + pReachable = &record; + } + continue; } + + + if (record.state == net::arp::State::STATE_STALE) { + if (record.nAge > nAgeStale) { + nAgeStale = record.nAge; + pStale = &record; + } + continue; + } + } + + if (pStale != nullptr) { + DEBUG_EXIT + return pStale; } - return false; + if (pReachable != nullptr) { + DEBUG_EXIT + return pReachable; + } + + DEBUG_EXIT + return nullptr; } -void arp_send_request(uint32_t nIp) { +static void arp_cache_update(const uint8_t *pMacAddress, const uint32_t nIp, const arp::Flags flag) { DEBUG_ENTRY - DEBUG_PRINTF(IPSTR, IP2STR(nIp)); + DEBUG_PRINTF(MACSTR " " IPSTR " flag=%d", MAC2STR(pMacAddress), IP2STR(nIp), flag); - s_requestType = net::arp::RequestType::REQUEST; + auto *record = arp_find_record(nIp, flag); - _pcast32 ip_addr; - ip_addr.u32 = nIp; + if (record == nullptr) { + assert(flag == arp::Flags::FLAG_UPDATE); + DEBUG_EXIT + return; + } - memcpy(s_arp_request.arp.target_ip, ip_addr.u8, IPv4_ADDR_LEN); + record->state = net::arp::State::STATE_REACHABLE; + record->nAge = 0; + std::memcpy(record->mac_address, pMacAddress, ETH_ADDR_LEN); - emac_eth_send(reinterpret_cast(&s_arp_request), sizeof(struct t_arp)); + arp_cache_record_dump(record); + + if (record->packet.p != nullptr) { + auto *udp = reinterpret_cast(record->packet.p); + std::memcpy(udp->ether.dst, record->mac_address, ETH_ADDR_LEN); + udp->ip4.chksum = 0; +#if !defined (CHECKSUM_BY_HARDWARE) + udp->ip4.chksum = net_chksum(reinterpret_cast(&udp->ip4), sizeof(udp->ip4)); +#endif +#if defined CONFIG_ENET_ENABLE_PTP + if (!record->packet.isTimestamp) { +#endif + emac_eth_send(record->packet.p, record->packet.nSize); +#if defined CONFIG_ENET_ENABLE_PTP + } else { + emac_eth_send_timestamp(record->packet.p, record->packet.nSize); + } +#endif + delete [] record->packet.p; + record->packet.p = nullptr; + } DEBUG_EXIT } -/* - * The Sender IP is set to all zeros, - * which means it cannot map to the Sender MAC address. - * The Target MAC address is all zeros, - * which means it cannot map to the Target IP address. - */ -void arp_send_probe() { +static void arp_send_request(const uint32_t nIp) { + DEBUG_PRINTF(IPSTR, IP2STR(nIp)); + + net::memcpy_ip(s_arp_request.arp.target_ip, nIp); + + emac_eth_send(reinterpret_cast(&s_arp_request), sizeof(struct t_arp)); +} + +template +static void arp_query(const uint32_t nDestinationIp, struct t_udp *pPacket, const uint32_t nSize, [[maybe_unused]] const arp::Flags flag) { DEBUG_ENTRY + DEBUG_PRINTF(IPSTR " %c", IP2STR(nDestinationIp), flag == arp::Flags::FLAG_UPDATE ? 'U' : 'I'); - s_requestType = net::arp::RequestType::PROBE; - s_isProbeReplyReceived = false; + auto *recordFound = arp_find_record(nDestinationIp, flag); + assert(recordFound != nullptr); - memset(s_arp_request.arp.sender_ip, 0, IPv4_ADDR_LEN); + arp_cache_record_dump(recordFound); + + if (recordFound->state == net::arp::State::STATE_EMPTY) { + recordFound->state = net::arp::State::STATE_PROBE; + recordFound->nAge = 0; + arp_send_request(nDestinationIp); + } + + if (recordFound->state == net::arp::State::STATE_PROBE) { + if (recordFound->packet.p != nullptr) { + delete[] recordFound->packet.p; + } - arp_send_request(net::globals::ipInfo.ip.addr); + recordFound->packet.p = new uint8_t[nSize]; + assert(recordFound->packet.p != nullptr); - _pcast32 ip_addr; - ip_addr.u32 = net::globals::ipInfo.ip.addr; - memcpy(s_arp_request.arp.sender_ip, ip_addr.u8, IPv4_ADDR_LEN); + net::memcpy(recordFound->packet.p, pPacket, nSize); + recordFound->packet.nSize = nSize; +#if defined CONFIG_ENET_ENABLE_PTP + recordFound->packet.isTimestamp = (S != net::arp::EthSend::IS_NORMAL); +#endif + } DEBUG_EXIT } -/* - * The packet structure is identical to the ARP Probe above, - * with the exception that a complete mapping exists. - * Both the Sender MAC address and the Sender IP address create a complete ARP mapping, - * and hosts on the network can use this pair of addresses in their ARP table. - */ -void arp_send_announcement() { - DEBUG_ENTRY +static void arp_cache_clean_record(net::arp::Record& record) { + if (record.packet.p != nullptr) { + delete[] record.packet.p; + } + memset(&record, 0, sizeof(struct net::arp::Record)); +} - s_requestType = net::arp::RequestType::ANNNOUNCEMENT; +static void arp_send_request_unicast(const uint32_t nIp, const uint8_t *pMacAddress) { + DEBUG_PRINTF(IPSTR, IP2STR(nIp)); - arp_send_request(net::globals::ipInfo.ip.addr); + net::memcpy(s_arp_request.ether.dst, pMacAddress , ETH_ADDR_LEN); + net::memcpy_ip(s_arp_request.arp.target_ip, nIp); - DEBUG_EXIT + emac_eth_send(reinterpret_cast(&s_arp_request), sizeof(struct t_arp)); + + memset(s_arp_request.ether.dst, 0xFF , ETH_ADDR_LEN); +} + +static void arp_timer() { + for (auto &record : s_ArpRecords) { + const auto state = record.state; + if (state != net::arp::State::STATE_EMPTY) { + record.nAge++; + + switch (state) { + case net::arp::State::STATE_PROBE: + if (record.nAge > net::arp::MAX_PROBING) { + arp_cache_clean_record(record); + } + break; + + case net::arp::State::STATE_REACHABLE: + if (record.nAge > net::arp::MAX_REACHABLE) { + record.state = net::arp::State::STATE_STALE; + record.nAge = 0; + } + break; + + case net::arp::State::STATE_STALE: + if (record.nAge > net::arp::MAX_STALE) { + record.state = net::arp::State::STATE_PROBE; + arp_send_request_unicast(record.nIp, record.mac_address); + } + break; + + default: + break; + } + } + } + + arp_cache_dump(); } -void arp_handle_request(struct t_arp *p_arp) { +static void arp_send_reply(const struct t_arp *p_arp) { DEBUG_ENTRY - _pcast32 target; + // Ethernet header + std::memcpy(s_arp_reply.ether.dst, p_arp->ether.src, ETH_ADDR_LEN); + // ARP Header + const auto nIpTarget = net::memcpy_ip(p_arp->arp.target_ip); + std::memcpy(s_arp_reply.arp.target_mac, p_arp->arp.sender_mac, ETH_ADDR_LEN); + std::memcpy(s_arp_reply.arp.target_ip, p_arp->arp.sender_ip, IPv4_ADDR_LEN); + net::memcpy_ip(s_arp_reply.arp.sender_ip, nIpTarget); - memcpy(target.u8, p_arp->arp.target_ip, IPv4_ADDR_LEN); + emac_eth_send(reinterpret_cast(&s_arp_reply), sizeof(struct t_arp)); - _pcast32 sender; + DEBUG_EXIT +} - memcpy(sender.u8, p_arp->arp.sender_ip, IPv4_ADDR_LEN); +// Public interface - DEBUG_PRINTF("Sender " IPSTR " Target " IPSTR, IP2STR(sender.u32), IP2STR(target.u32)); +void __attribute__((cold)) arp_init() { + DEBUG_ENTRY - if (!((target.u32 == net::globals::ipInfo.ip.addr) || (target.u32 == net::globals::ipInfo.secondary_ip.addr) || (target.u32 == net::globals::ipInfo.broadcast_ip.addr))) { - DEBUG_PUTS("No for me."); - DEBUG_EXIT - return; + for (auto& record : s_ArpRecords) { + std::memset(&record, 0, sizeof(struct net::arp::Record)); } + // ARP Request template // Ethernet header - memcpy(s_arp_reply.ether.dst, p_arp->ether.src, ETH_ADDR_LEN); + std::memcpy(s_arp_request.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); + std::memset(s_arp_request.ether.dst, 0xFF , ETH_ADDR_LEN); + s_arp_request.ether.type = __builtin_bswap16(ETHER_TYPE_ARP); + // ARP Header - memcpy(s_arp_reply.arp.target_mac, p_arp->arp.sender_mac, ETH_ADDR_LEN); - memcpy(s_arp_reply.arp.target_ip, p_arp->arp.sender_ip, IPv4_ADDR_LEN); - memcpy(s_arp_reply.arp.sender_ip, target.u8, IPv4_ADDR_LEN); + s_arp_request.arp.hardware_type = __builtin_bswap16(ARP_HWTYPE_ETHERNET); + s_arp_request.arp.protocol_type = __builtin_bswap16(ARP_PRTYPE_IPv4); + s_arp_request.arp.hardware_size = ARP_HARDWARE_SIZE; + s_arp_request.arp.protocol_size = ARP_PROTOCOL_SIZE; + s_arp_request.arp.opcode = __builtin_bswap16(ARP_OPCODE_RQST); - emac_eth_send(reinterpret_cast(&s_arp_reply), sizeof(struct t_arp)); + std::memcpy(s_arp_request.arp.sender_mac, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); + net::memcpy_ip(s_arp_request.arp.sender_ip, net::globals::netif_default.ip.addr); + std::memset(s_arp_request.arp.target_mac, 0x00, ETH_ADDR_LEN); + + // ARP Reply Template + // Ethernet header + std::memcpy(s_arp_reply.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); + s_arp_reply.ether.type = __builtin_bswap16(ETHER_TYPE_ARP); + + // ARP Header + s_arp_reply.arp.hardware_type = __builtin_bswap16(ARP_HWTYPE_ETHERNET); + s_arp_reply.arp.protocol_type = __builtin_bswap16(ARP_PRTYPE_IPv4); + s_arp_reply.arp.hardware_size = ARP_HARDWARE_SIZE; + s_arp_reply.arp.protocol_size = ARP_PROTOCOL_SIZE; + s_arp_reply.arp.opcode = __builtin_bswap16(ARP_OPCODE_REPLY); + + std::memcpy(s_arp_reply.arp.sender_mac, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); + + Hardware::Get()->SoftwareTimerAdd(net::arp::TIMER_INTERVAL, arp_timer); DEBUG_EXIT } -void arp_handle_reply(struct t_arp *p_arp) { - DEBUG_ENTRY - - switch (s_requestType) { - case net::arp::RequestType::REQUEST: { - _pcast32 sender; - memcpy(sender.u8, p_arp->arp.sender_ip, IPv4_ADDR_LEN); - arp_cache_update(p_arp->arp.sender_mac, sender.u32); +__attribute__((hot)) void arp_handle(struct t_arp *pArp) { + /* + * RFC 826 Packet Reception: + */ + if (__builtin_expect(((pArp->arp.hardware_type != __builtin_bswap16(ARP_HWTYPE_ETHERNET)) + || (pArp->arp.protocol_type != __builtin_bswap16(ARP_PRTYPE_IPv4)) + || (pArp->arp.hardware_size != ARP_HARDWARE_SIZE) + || (pArp->arp.protocol_size != ARP_PROTOCOL_SIZE)), 0)) { + DEBUG_EXIT + return; } + + acd_arp_reply(pArp); + + /* ARP packet directed to us? */ + const auto nIpTarget = net::memcpy_ip(pArp->arp.target_ip); + const auto bToUs = ((nIpTarget == net::globals::netif_default.ip.addr) || (nIpTarget == net::globals::netif_default.secondary_ip.addr)); + /* ARP packet from us? */ + const auto bFromUs = (net::memcpy_ip(pArp->arp.sender_ip) == net::globals::netif_default.ip.addr); + + DEBUG_PRINTF("bToUs:%d, bFromUs:%d", bToUs, bFromUs); + + /* + * ARP message directed to us? + * -> add IP address in ARP cache; assume requester wants to talk to us, + * can result in directly sending the queued packets for this host. + * ARP message not directed to us? + * -> update the source IP address in the cache, if present + */ + arp_cache_update(pArp->arp.sender_mac, net::memcpy_ip(pArp->arp.sender_ip), bToUs ? arp::Flags::FLAG_INSERT : arp::Flags::FLAG_UPDATE); + + switch (pArp->arp.opcode) { + case __builtin_bswap16(ARP_OPCODE_RQST): + if (bToUs && !bFromUs) { + arp_send_reply(pArp); + } else { + DEBUG_PUTS("ARP request was not for us"); + } break; - case net::arp::RequestType::PROBE: - s_isProbeReplyReceived = true; + case __builtin_bswap16(ARP_OPCODE_REPLY): + /* Cache update is handled earlier */ break; default: - assert(0); - __builtin_unreachable(); + DEBUG_PRINTF("opcode %04x not handled", __builtin_bswap16(pArp->arp.opcode)); break; } +} + +template +static void arp_send_implementation(struct t_udp *pPacket, const uint32_t nSize, const uint32_t nRemoteIp) { + DEBUG_ENTRY + DEBUG_PRINTF(IPSTR, IP2STR(nRemoteIp)); + + net::memcpy_ip(pPacket->ip4.dst, nRemoteIp); + pPacket->ip4.chksum = 0; +#if !defined (CHECKSUM_BY_HARDWARE) + pPacket->ip4.chksum = net_chksum(reinterpret_cast(&pPacket->ip4), sizeof(pPacket->ip4)); +#endif + + auto nDestinationIp = nRemoteIp; + + if (__builtin_expect((net::globals::nOnNetworkMask != (nRemoteIp & net::globals::nOnNetworkMask)), 0)) { + /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with + a link-local source address must always be "directly to its destination + on the same physical link. The host MUST NOT send the packet to any + router for forwarding". */ + if (!network::is_linklocal_ip(nRemoteIp)) { + nDestinationIp = net::globals::netif_default.gw.addr; + DEBUG_PUTS(""); + } + } + + for (auto &record : s_ArpRecords) { + if (record.state >= net::arp::State::STATE_REACHABLE) { + if (record.nIp == nDestinationIp) { + std::memcpy(pPacket->ether.dst, record.mac_address, ETH_ADDR_LEN); + + if (S == net::arp::EthSend::IS_NORMAL) { + emac_eth_send(reinterpret_cast(pPacket), nSize); + } +#if defined CONFIG_ENET_ENABLE_PTP + else if (S == net::arp::EthSend::IS_TIMESTAMP) { + emac_eth_send_timestamp(reinterpret_cast(pPacket), nSize); + } +#endif + DEBUG_EXIT + return; + } + } + } + + arp_query(nDestinationIp, pPacket, nSize, arp::Flags::FLAG_INSERT); DEBUG_EXIT + return; } -__attribute__((hot)) void arp_handle(struct t_arp *pArp) { +void arp_send(struct t_udp *pPacket, const uint32_t nSize, const uint32_t nRemoteIp) { + arp_send_implementation(pPacket, nSize, nRemoteIp); +} + +#if defined CONFIG_ENET_ENABLE_PTP +void arp_send_timestamp(struct t_udp *pPacket, const uint32_t nSize, const uint32_t nRemoteIp) { + arp_send_implementation(pPacket, nSize, nRemoteIp); +} +#endif + +/* + * The Sender IP is set to all zeros, + * which means it cannot map to the Sender MAC address. + * The Target MAC address is all zeros, + * which means it cannot map to the Target IP address. + */ +void arp_acd_probe(const ip4_addr_t ipaddr) { DEBUG_ENTRY - switch (pArp->arp.opcode) { - case __builtin_bswap16(ARP_OPCODE_RQST): - arp_handle_request(pArp); - break; - case __builtin_bswap16(ARP_OPCODE_REPLY): - arp_handle_reply(pArp); - break; - default: - DEBUG_PRINTF("opcode %04x not handled", __builtin_bswap16(pArp->arp.opcode)); - break; - } + memset(s_arp_request.arp.sender_ip, 0, IPv4_ADDR_LEN); + net::memcpy_ip(s_arp_request.arp.target_ip, ipaddr.addr); + + emac_eth_send(reinterpret_cast(&s_arp_request), sizeof(struct t_arp)); + + net::memcpy_ip(s_arp_request.arp.sender_ip, net::globals::netif_default.ip.addr); DEBUG_EXIT } + +/* + * The packet structure is identical to the ARP Probe above, + * with the exception that a complete mapping exists. + * Both the Sender MAC address and the Sender IP address create a complete ARP mapping, + * and hosts on the network can use this pair of addresses in their ARP table. + */ +void arp_acd_send_announcement(const ip4_addr_t ipaddr) { + net::memcpy_ip(s_arp_request.arp.target_ip, ipaddr.addr); + net::memcpy_ip(s_arp_request.arp.sender_ip, ipaddr.addr); + + emac_eth_send(reinterpret_cast(&s_arp_request), sizeof(struct t_arp)); +} +} // namespace net diff --git a/lib-network/src/net/arp_cache.cpp b/lib-network/src/net/arp_cache.cpp deleted file mode 100644 index 97f2795..0000000 --- a/lib-network/src/net/arp_cache.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file arp_cache.cpp - * - */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include "net_private.h" -#include "net_packets.h" -#include "net_platform.h" -#include "net_debug.h" - -#include "emac/net_link_check.h" - -#include "../../config/net_config.h" - -#if !defined ARP_MAX_RECORDS -static constexpr auto MAX_RECORDS = 32; -#else -static constexpr auto MAX_RECORDS = ARP_MAX_RECORDS; -#endif - -struct ArpRecord { - uint32_t nIp; - uint8_t mac_address[ETH_ADDR_LEN]; -}; - -typedef union pcast32 { - uint32_t u32; - uint8_t u8[4]; -} _pcast32; - -static ArpRecord s_ArpRecords[MAX_RECORDS] SECTION_NETWORK ALIGNED; -static uint16_t s_Entries SECTION_NETWORK ALIGNED; - -#ifndef NDEBUG -# define TICKER_COUNT 100 ///< 10 seconds - static volatile uint32_t s_ticker ; -#endif - -void __attribute__((cold)) arp_cache_init() { - s_Entries = 0; - - for (auto& record : s_ArpRecords) { - memset(&record, 0, sizeof(struct ArpRecord)); - } - -#ifndef NDEBUG - s_ticker = TICKER_COUNT; -#endif -} - -void arp_cache_update(const uint8_t *pMacAddress, uint32_t nIp) { - DEBUG_ENTRY - DEBUG_PRINTF(MACSTR " " IPSTR, MAC2STR(pMacAddress), IP2STR(nIp)); - - if (s_Entries == MAX_RECORDS) { - console_error("ARP cache is full\n"); - return; - } - - for (auto i = 0; i < s_Entries; i++) { - if (s_ArpRecords[i].nIp == nIp) { - DEBUG_EXIT - return; - } - } - - memcpy(s_ArpRecords[s_Entries].mac_address, pMacAddress, ETH_ADDR_LEN); - s_ArpRecords[s_Entries].nIp = nIp; - - s_Entries++; - - DEBUG_EXIT -} - -uint32_t arp_cache_lookup(uint32_t nIp, uint8_t *pMacAddress) { - DEBUG_ENTRY - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(nIp), MAC2STR(pMacAddress)); - - uint32_t i; - - for (i = 0; i < MAX_RECORDS; i++) { - if (s_ArpRecords[i].nIp == nIp) { - memcpy(pMacAddress, s_ArpRecords[i].mac_address, ETH_ADDR_LEN); - DEBUG_EXIT - return nIp; - } - - if (s_ArpRecords[i].nIp == 0) { - break; - } - } - - if (net::link_status_read() == net::Link::STATE_DOWN) { - DEBUG_EXIT - return 0; - } - - const auto nEntries = s_Entries; - int32_t nTimeout; - auto nRetries = 3; - - while (nRetries--) { - arp_send_request(nIp); - - nTimeout = 0x1FFFF; -#ifndef NDEBUG - nTimeout+= 0x40000; -#endif - - while ((nTimeout-- > 0) && (nEntries == s_Entries)) { - net_handle(); - } - - if (nEntries != s_Entries) { - memcpy(pMacAddress, s_ArpRecords[nEntries].mac_address, ETH_ADDR_LEN); - DEBUG_PRINTF("timeout=%x", nTimeout); - DEBUG_EXIT - return nIp; - } - - DEBUG_PRINTF("timeout=%d, current_entry=%d, s_entry_current=%d", nTimeout, nEntries, s_Entries); - } - - DEBUG_EXIT - return 0; -} - -void arp_cache_dump() { -#ifndef NDEBUG - printf("ARP Cache size=%d\n", s_Entries); - - for (auto i = 0; i < s_Entries; i++) { - printf("%02d " IPSTR " " MACSTR "\n", i, IP2STR(s_ArpRecords[i].nIp),MAC2STR(s_ArpRecords[i].mac_address)); - } -#endif -} - -#ifndef NDEBUG -void arp_cache_timer(void) { - s_ticker--; - - if (s_ticker == 0) { - s_ticker = TICKER_COUNT; - arp_cache_dump(); - } -} -#endif diff --git a/lib-network/src/net/autoip.cpp b/lib-network/src/net/autoip.cpp new file mode 100755 index 0000000..cb2fedf --- /dev/null +++ b/lib-network/src/net/autoip.cpp @@ -0,0 +1,172 @@ +/** + * @file autoip.cpp + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* This code is inspired by the lwIP TCP/IP stack. + * https://savannah.nongnu.org/projects/lwip/ + */ +/** + * The autoip.cpp aims to be conform to RFC 3927. + * https://datatracker.ietf.org/doc/html/rfc3927 + * Dynamic Configuration of IPv4 Link-Local Addresses + */ + +#ifdef DEBUG_AUTOIP +# undef NDEBUG +#endif + +#include +#include + +#include "netif.h" +#include "net/autoip.h" +#include "net/protocol/autoip.h" +#include "net/acd.h" +#include "net/arp.h" + +#include "debug.h" + +namespace net { +static void autoip_bind(){ + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + assert(autoip != nullptr); + + autoip->state = autoip::State::AUTOIP_STATE_BOUND; + + ip4_addr_t sn_mask, gw_addr; + + sn_mask.addr = network::convert_to_uint(255,255,0,0); + gw_addr.addr = 0; + + netif_set_addr(autoip->llipaddr, sn_mask, gw_addr); +} + +static void autoip_restart() { + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + assert(autoip != nullptr); + + autoip->tried_llipaddr++; + autoip_start(); +} + +static void autoip_conflict_callback(net::acd::Callback state) { + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + assert(autoip != nullptr); + + switch (state) { + case net::acd::Callback::ACD_IP_OK: + autoip_bind(); + netif_set_flags(netif::NETIF_FLAG_AUTOIP_OK); + break; + case net::acd::Callback::ACD_RESTART_CLIENT: + autoip_restart(); + break; + case net::acd::Callback::ACD_DECLINE: + /* "delete" conflicting address so a new one will be selected in autoip_start() */ + autoip->llipaddr.addr = network::IP4_ANY; + autoip_stop(); + netif_clear_flags(netif::NETIF_FLAG_AUTOIP_OK); + break; + default: + break; + } +} + +static void autoip_create_addr(uint32_t &ipaddr) { + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + assert(autoip != nullptr); + + /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * compliant to RFC 3927 Section 2.1 */ + const auto mask = globals::netif_default.hwaddr[3] + (globals::netif_default.hwaddr[4] << 8); + ipaddr = static_cast(mask << 16) | autoip::AUTOIP_RANGE_START; + ipaddr = __builtin_bswap32(ipaddr); + + ipaddr += autoip->tried_llipaddr; + ipaddr = __builtin_bswap32(autoip::AUTOIP_NET) | (ipaddr & 0xffff); + + if (ipaddr < __builtin_bswap32(autoip::AUTOIP_RANGE_START)) { + ipaddr += __builtin_bswap32(autoip::AUTOIP_RANGE_END) - __builtin_bswap32(autoip::AUTOIP_RANGE_START) + 1; + } + + if (ipaddr > __builtin_bswap32(autoip::AUTOIP_RANGE_END)) { + ipaddr -= __builtin_bswap32(autoip::AUTOIP_RANGE_END) - __builtin_bswap32(autoip::AUTOIP_RANGE_START) + 1; + } + + ipaddr = __builtin_bswap32(ipaddr); + + DEBUG_PRINTF(IPSTR, IP2STR(ipaddr)); +} + +/* + * Public interface + */ + +void autoip_start() { + DEBUG_ENTRY + + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + + if (autoip == nullptr) { + autoip = new (struct autoip::Autoip); + assert(autoip != nullptr); + memset(autoip, 0, sizeof(struct autoip::Autoip)); + } + + if (autoip->state == autoip::State::AUTOIP_STATE_OFF) { + acd_add(&autoip->acd, autoip_conflict_callback); + + /* In accordance to RFC3927 section 2.1: + * Keep using the same link local address as much as possible. + * Only when there is none or when there was a conflict, select a new one. + */ + if (!network::is_linklocal_ip(autoip->llipaddr.addr)) { + autoip_create_addr(autoip->llipaddr.addr); + } + + autoip->state = autoip::State::AUTOIP_STATE_CHECKING; + acd_start(&autoip->acd, autoip->llipaddr); + } else { + DEBUG_PUTS("Already started"); + } + + DEBUG_EXIT +} + +void autoip_stop() { + DEBUG_ENTRY + auto *autoip = reinterpret_cast(globals::netif_default.autoip); + + if (autoip != nullptr) { + autoip->state = autoip::State::AUTOIP_STATE_OFF; + + ip4_addr_t any; + any.addr = network::IP4_ANY; + + if (network::is_linklocal_ip(globals::netif_default.ip.addr)) { + netif_set_addr(any, any, any); + } + } + + DEBUG_EXIT +} +} // namespace net diff --git a/lib-network/src/net/dhcp.cpp b/lib-network/src/net/dhcp.cpp old mode 100644 new mode 100755 index a160ece..7bc1f30 --- a/lib-network/src/net/dhcp.cpp +++ b/lib-network/src/net/dhcp.cpp @@ -1,8 +1,7 @@ /** * @file dhcp.cpp - * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,372 +21,852 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +/* This code is inspired by the lwIP TCP/IP stack. + * https://savannah.nongnu.org/projects/lwip/ + */ + +#if defined (DEBUG_NET_DHCP) +# undef NDEBUG +#endif + +#pragma GCC push_options +#pragma GCC optimize ("Os") #include #include #include -#include "dhcp_internal.h" - #include "net.h" +#include "net_memcpy.h" #include "net_private.h" #include "hardware.h" +#include "network.h" #include "../../config/net_config.h" -namespace net { -namespace globals { -extern struct IpInfo ipInfo; -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net +#include "net/dhcp.h" +#include "net/protocol/dhcp.h" +#include "net/protocol/iana.h" +#include "net/acd.h" +#include "net/autoip.h" +#include "netif.h" -typedef union pcast32 { - uint32_t u32; - uint8_t u8[4]; -} _pcast32; +#define REBOOT_TRIES 2 + +static int32_t nTimerId; // https://tools.ietf.org/html/rfc1541 +namespace net { +static dhcp::Message s_dhcp_message SECTION_NETWORK ALIGNED; + +static void message_init() { + memset(&s_dhcp_message, 0, sizeof(dhcp::Message)); -namespace dhcp { -struct Message { - uint8_t op; - uint8_t htype; - uint8_t hlen; - uint8_t hops; - uint32_t xid; - uint16_t secs; - uint16_t flags; - uint8_t ciaddr[IPv4_ADDR_LEN]; - uint8_t yiaddr[IPv4_ADDR_LEN]; - uint8_t siaddr[IPv4_ADDR_LEN]; - uint8_t giaddr[IPv4_ADDR_LEN]; - uint8_t chaddr[16]; - uint8_t sname[64]; - uint8_t file[128]; - uint8_t options[DHCP_OPT_SIZE]; -}PACKED; -} // namespace dhcp - -enum OPTIONS { - OPTIONS_PAD_OPTION = 0, - OPTIONS_SUBNET_MASK = 1, - OPTIONS_ROUTERS_ON_SUBNET = 3, - OPTIONS_DNS = 6, - OPTIONS_HOSTNAME = 12, - OPTIONS_DOMAIN_NAME = 15, - OPTIONS_REQUESTED_IP = 50, - OPTIONS_MESSAGE_TYPE = 53, - OPTIONS_SERVER_IDENTIFIER = 54, - OPTIONS_PARAM_REQUEST = 55, - OPTIONS_DHCP_T1_VALUE = 58, - OPTIONS_DHCP_T2_VALUE = 59, - OPTIONS_CLIENT_IDENTIFIER = 61, - OPTIONS_END_OPTION = 255 -}; - -static dhcp::Message s_dhcp_message ALIGNED; - -static uint8_t s_dhcp_server_ip[IPv4_ADDR_LEN] ALIGNED = { 0, }; -static uint8_t s_dhcp_allocated_ip[IPv4_ADDR_LEN] ALIGNED = { 0, }; -static uint8_t s_dhcp_allocated_gw[IPv4_ADDR_LEN] ALIGNED = { 0, }; -static uint8_t s_dhcp_allocated_netmask[IPv4_ADDR_LEN] ALIGNED = { 0, }; - -static void message_init(const uint8_t *pMacAddress) { - auto *p = reinterpret_cast(&s_dhcp_message); - - for (uint32_t i = 0; i < sizeof(dhcp::Message); i++) { - *p++ = 0; - } - - s_dhcp_message.op = DHCP_OP_BOOTREQUEST; - s_dhcp_message.htype = DHCP_HTYPE_10MB; // This is the current default - s_dhcp_message.hlen = ETH_ADDR_LEN; - memcpy(s_dhcp_message.chaddr, pMacAddress, ETH_ADDR_LEN); - - s_dhcp_message.options[0] = static_cast((MAGIC_COOKIE & 0xFF000000) >> 24); - s_dhcp_message.options[1] = static_cast((MAGIC_COOKIE & 0x00FF0000) >> 16); - s_dhcp_message.options[2] = static_cast((MAGIC_COOKIE & 0x0000FF00) >> 8); - s_dhcp_message.options[3] = static_cast(MAGIC_COOKIE & 0x000000FF) >> 0; - - s_dhcp_message.options[4] = OPTIONS_MESSAGE_TYPE; + s_dhcp_message.op = dhcp::OpCode::BOOTREQUEST; + s_dhcp_message.htype = dhcp::HardwareType::HTYPE_10MB; // This is the current default + s_dhcp_message.hlen = network::MAC_SIZE; + memcpy(s_dhcp_message.chaddr, net::globals::netif_default.hwaddr, network::MAC_SIZE); + + s_dhcp_message.options[0] = static_cast((dhcp::MAGIC_COOKIE & 0xFF000000) >> 24); + s_dhcp_message.options[1] = static_cast((dhcp::MAGIC_COOKIE & 0x00FF0000) >> 16); + s_dhcp_message.options[2] = static_cast((dhcp::MAGIC_COOKIE & 0x0000FF00) >> 8); + s_dhcp_message.options[3] = static_cast(dhcp::MAGIC_COOKIE & 0x000000FF) >> 0; + + s_dhcp_message.options[4] = dhcp::Options::OPTION_MESSAGE_TYPE; s_dhcp_message.options[5] = 0x01; } -static void send_discover(int nHandle, const uint8_t *pMacAddress) { +static void dhcp_update_msg(const uint8_t message_type) { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */ + if ((message_type != dhcp::Type::REQUEST) || (dhcp->state == dhcp::State::STATE_REBOOTING)) { + /* reuse transaction identifier in retransmissions */ + if (dhcp->tries == 0) { + auto xid = __builtin_bswap32(dhcp->xid); + xid++; + dhcp->xid = __builtin_bswap32(xid); + } + } + + s_dhcp_message.xid = dhcp->xid; + + if ((message_type == dhcp::Type::INFORM) + || (message_type == dhcp::Type::DECLINE) + || (message_type == dhcp::Type::RELEASE) + || ((message_type == dhcp::Type::REQUEST) + && /* DHCP_STATE_BOUND not used for sending! */ + ((dhcp->state == dhcp::State::STATE_RENEWING) || dhcp->state == dhcp::State::STATE_REBINDING))) { + + const auto &netif = net::globals::netif_default; + net::memcpy_ip(s_dhcp_message.ciaddr, netif.ip.addr); + } +} + +static void send_discover() { DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + dhcp_update_msg(dhcp::Type::DISCOVER); uint32_t k = 6; - s_dhcp_message.options[k++] = DCHP_TYPE_DISCOVER; + s_dhcp_message.options[k++] = dhcp::Type::DISCOVER; - s_dhcp_message.options[k++] = OPTIONS_CLIENT_IDENTIFIER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_CLIENT_IDENTIFIER; s_dhcp_message.options[k++] = 0x07; s_dhcp_message.options[k++] = 0x01; - s_dhcp_message.options[k++] = pMacAddress[0]; - s_dhcp_message.options[k++] = pMacAddress[1]; - s_dhcp_message.options[k++] = pMacAddress[2]; - s_dhcp_message.options[k++] = pMacAddress[3]; - s_dhcp_message.options[k++] = pMacAddress[4]; - s_dhcp_message.options[k++] = pMacAddress[5]; - - s_dhcp_message.options[k++] = OPTIONS_PARAM_REQUEST; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[0]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[1]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[2]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[3]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[4]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[5]; + + s_dhcp_message.options[k++] = dhcp::Options::OPTION_PARAM_REQUEST; s_dhcp_message.options[k++] = 0x06; // length of request - s_dhcp_message.options[k++] = OPTIONS_SUBNET_MASK; - s_dhcp_message.options[k++] = OPTIONS_ROUTERS_ON_SUBNET; - s_dhcp_message.options[k++] = OPTIONS_DNS; - s_dhcp_message.options[k++] = OPTIONS_DOMAIN_NAME; - s_dhcp_message.options[k++] = OPTIONS_DHCP_T1_VALUE; - s_dhcp_message.options[k++] = OPTIONS_DHCP_T2_VALUE; - s_dhcp_message.options[k++] = OPTIONS_END_OPTION; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_SUBNET_MASK; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_ROUTER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DOMAIN_NAME; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_LEASE_TIME; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DHCP_T1_VALUE; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DHCP_T2_VALUE; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_END; - udp_send(nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - DHCP_OPT_SIZE), IP_BROADCAST, DHCP_PORT_SERVER); + udp_send(dhcp->nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - dhcp::OPT_SIZE), network::IP4_BROADCAST, net::iana::IANA_PORT_DHCP_SERVER); DEBUG_EXIT } -static void _send_request(int idx, const uint8_t *pMacAddress, const char *pHostname) { +static void send_request() { DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); uint32_t i; uint32_t k = 6; - s_dhcp_message.options[k++] = DCHP_TYPE_REQUEST; + s_dhcp_message.options[k++] = dhcp::Type::REQUEST; - s_dhcp_message.options[k++] = OPTIONS_CLIENT_IDENTIFIER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_CLIENT_IDENTIFIER; s_dhcp_message.options[k++] = 0x07; s_dhcp_message.options[k++] = 0x01; - s_dhcp_message.options[k++] = pMacAddress[0]; - s_dhcp_message.options[k++] = pMacAddress[1]; - s_dhcp_message.options[k++] = pMacAddress[2]; - s_dhcp_message.options[k++] = pMacAddress[3]; - s_dhcp_message.options[k++] = pMacAddress[4]; - s_dhcp_message.options[k++] = pMacAddress[5]; - - s_dhcp_message.options[k++] = OPTIONS_REQUESTED_IP; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[0]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[1]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[2]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[3]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[4]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[5]; + + s_dhcp_message.options[k++] = dhcp::Options::OPTION_REQUESTED_IP; s_dhcp_message.options[k++] = 0x04; - s_dhcp_message.options[k++] = s_dhcp_allocated_ip[0]; - s_dhcp_message.options[k++] = s_dhcp_allocated_ip[1]; - s_dhcp_message.options[k++] = s_dhcp_allocated_ip[2]; - s_dhcp_message.options[k++] = s_dhcp_allocated_ip[3]; + memcpy_ip(&s_dhcp_message.options[k], dhcp->offered.offered_ip_addr.addr); + k = k + 4; - s_dhcp_message.options[k++] = OPTIONS_SERVER_IDENTIFIER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_SERVER_IDENTIFIER; s_dhcp_message.options[k++] = 0x04; - s_dhcp_message.options[k++] = s_dhcp_server_ip[0]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[1]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[2]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[3]; + memcpy_ip(&s_dhcp_message.options[k], dhcp->server_ip_addr.addr); + k = k + 4; - s_dhcp_message.options[k++] = OPTIONS_HOSTNAME; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_HOSTNAME; s_dhcp_message.options[k++] = 0; // length of hostname - for (i = 0; pHostname[i] != 0; i++) { - s_dhcp_message.options[k++] = pHostname[i]; + for (i = 0; net::globals::netif_default.hostname[i] != 0; i++) { + s_dhcp_message.options[k++] = net::globals::netif_default.hostname[i]; } s_dhcp_message.options[k - (i + 1)] = static_cast(i); // length of hostname - s_dhcp_message.options[k++] = OPTIONS_PARAM_REQUEST; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_PARAM_REQUEST; s_dhcp_message.options[k++] = 0x06; // length of request - s_dhcp_message.options[k++] = OPTIONS_SUBNET_MASK; - s_dhcp_message.options[k++] = OPTIONS_ROUTERS_ON_SUBNET; - s_dhcp_message.options[k++] = OPTIONS_DNS; - s_dhcp_message.options[k++] = OPTIONS_DOMAIN_NAME; - s_dhcp_message.options[k++] = OPTIONS_DHCP_T1_VALUE; - s_dhcp_message.options[k++] = OPTIONS_DHCP_T2_VALUE; - s_dhcp_message.options[k++] = OPTIONS_END_OPTION; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_SUBNET_MASK; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_ROUTER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DNS_SERVER; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DOMAIN_NAME; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DHCP_T1_VALUE; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_DHCP_T2_VALUE; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_END; - udp_send(idx, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - DHCP_OPT_SIZE), IP_BROADCAST, DHCP_PORT_SERVER); + udp_send(dhcp->nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - dhcp::OPT_SIZE), network::IP4_BROADCAST, net::iana::IANA_PORT_DHCP_SERVER); DEBUG_EXIT } -static int parse_response(int nHandle, const uint8_t *pMacAddress) { - uint8_t *pResponse; - const auto nMillis = Hardware::Get()->Millis(); - uint32_t nSize = 0; +static void dhcp_send_release(const uint32_t nDestinationIp) { + DEBUG_ENTRY + DEBUG_PRINTF(IPSTR, IP2STR(nDestinationIp)); + + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); - do { - net_handle(); + uint32_t k = 6; - uint32_t nFromIp; - uint16_t nFromPort; + s_dhcp_message.options[k++] = dhcp::Type::RELEASE; - nSize = udp_recv2(nHandle, const_cast(&pResponse), &nFromIp, &nFromPort); + s_dhcp_message.options[k++] = dhcp::Options::OPTION_SERVER_IDENTIFIER; + s_dhcp_message.options[k++] = 0x04; + net::memcpy_ip(&s_dhcp_message.options[k], dhcp->server_ip_addr.addr); + k = k + 4; - if ((nSize > 0) && (nFromPort == DHCP_PORT_SERVER)) { + s_dhcp_message.options[k++] = dhcp::Options::OPTION_END; - const auto *const pDhcpMessage = reinterpret_cast(pResponse); + udp_send(dhcp->nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - dhcp::OPT_SIZE), nDestinationIp, net::iana::IANA_PORT_DHCP_SERVER); - if (memcmp(pDhcpMessage->chaddr, pMacAddress, ETH_ADDR_LEN) == 0) { - break; - } - } - } while ((Hardware::Get()->Millis() - nMillis) < 500); + DEBUG_EXIT +} - DEBUG_PRINTF("timeout %u", Hardware::Get()->Millis() - nMillis); +void dhcp_inform() { + DEBUG_ENTRY - int type = 0; - uint8_t opt_len = 0; + const auto nHandle = udp_begin(net::iana::IANA_PORT_DHCP_CLIENT); +#ifndef NDEBUG + if (nHandle < 0) { + console_error("DHCP Inform\n"); + return; + } +#endif - if (nSize > 0) { - auto *p = pResponse; - p = p + sizeof(dhcp::Message) - DHCP_OPT_SIZE + 4; - auto *e = pResponse + nSize; - - while (p < e) { - switch (*p) { - case OPTIONS_END_OPTION: - p = e; - break; - case OPTIONS_PAD_OPTION: - p++; - break; - case OPTIONS_MESSAGE_TYPE: - p++; - p++; - type = *p++; - break; - case OPTIONS_SUBNET_MASK: - p++; - p++; - s_dhcp_allocated_netmask[0] = *p++; - s_dhcp_allocated_netmask[1] = *p++; - s_dhcp_allocated_netmask[2] = *p++; - s_dhcp_allocated_netmask[3] = *p++; - break; - case OPTIONS_ROUTERS_ON_SUBNET: - p++; - opt_len = *p++; - s_dhcp_allocated_gw[0] = *p++; - s_dhcp_allocated_gw[1] = *p++; - s_dhcp_allocated_gw[2] = *p++; - s_dhcp_allocated_gw[3] = *p++; - p = p + (opt_len - 4); - break; - case OPTIONS_SERVER_IDENTIFIER : - p++; - opt_len = *p++; - s_dhcp_server_ip[0] = *p++; - s_dhcp_server_ip[1] = *p++; - s_dhcp_server_ip[2] = *p++; - s_dhcp_server_ip[3] = *p++; - break; - default: - p++; - opt_len = *p++; - p += opt_len; - break; - } - } + message_init(); + net::memcpy_ip(&s_dhcp_message.ciaddr[0], net::globals::netif_default.ip.addr); + + uint32_t k = 6; + + s_dhcp_message.options[k++] = dhcp::Type::INFORM; + + s_dhcp_message.options[k++] = dhcp::Options::OPTION_CLIENT_IDENTIFIER; + s_dhcp_message.options[k++] = 0x07; + s_dhcp_message.options[k++] = 0x01; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[0]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[1]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[2]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[3]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[4]; + s_dhcp_message.options[k++] = net::globals::netif_default.hwaddr[5]; + + s_dhcp_message.options[k++] = dhcp::Options::OPTION_END; + + udp_send(nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - dhcp::OPT_SIZE), network::IP4_BROADCAST, net::iana::IANA_PORT_DHCP_SERVER); + udp_end(net::iana::IANA_PORT_DHCP_CLIENT); + + DEBUG_EXIT +} + +#define SET_TIMEOUT_FROM_OFFERED(result, offered, min, max) do { \ + uint32_t timeout = (offered + dhcp::DHCP_COARSE_TIMER_SECS / 2) / dhcp::DHCP_COARSE_TIMER_SECS; \ + if (timeout > max) { \ + timeout = max; \ + } \ + if (timeout == min) { \ + timeout = 1; \ + } \ + result = static_cast(timeout); \ +} while(0) + +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T0_LEASE(res, dhcp) SET_TIMEOUT_FROM_OFFERED(res, (dhcp)->offered.offered_t0_lease, 0, 0xffff) +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T1_RENEW(res, dhcp) SET_TIMEOUT_FROM_OFFERED(res, (dhcp)->offered.offered_t1_renew, 0, 0xffff) +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T2_REBIND(res, dhcp) SET_TIMEOUT_FROM_OFFERED(res, (dhcp)->offered.offered_t2_rebind, 0, 0xffff) + +#define DHCP_NEXT_TIMEOUT_THRESHOLD ((60 + net::dhcp::DHCP_COARSE_TIMER_SECS / 2) / net::dhcp::DHCP_COARSE_TIMER_SECS) +#define DHCP_REQUEST_BACKOFF_SEQUENCE(tries) (( (tries) < 6U ? 1U << (tries) : 60U) * 1000U) + +static void dhcp_set_state(struct dhcp::Dhcp *dhcp, dhcp::State new_state) { + if (new_state != dhcp->state) { + DEBUG_PRINTF("%u -> %u", static_cast(dhcp->state), static_cast(new_state)); + + dhcp->state = new_state; + dhcp->tries = 0; + dhcp->request_timeout = 0; + } +} + +static void dhcp_bind() { + DEBUG_ENTRY + + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + /* reset time used of lease */ + dhcp->lease_used = 0; - if (type == DCHP_TYPE_OFFER) { - const auto *const pDhcpMessage = reinterpret_cast(pResponse); - s_dhcp_allocated_ip[0] = pDhcpMessage->yiaddr[0]; - s_dhcp_allocated_ip[1] = pDhcpMessage->yiaddr[1]; - s_dhcp_allocated_ip[2] = pDhcpMessage->yiaddr[2]; - s_dhcp_allocated_ip[3] = pDhcpMessage->yiaddr[3]; + if (dhcp->offered.offered_t0_lease != 0xffffffffUL) { + /* set renewal period timer */ + DHCP_SET_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp->t0_timeout, dhcp); + } + + /* temporary DHCP lease? */ + if (dhcp->offered.offered_t1_renew != 0xffffffffUL) { + /* set renewal period timer */ + DHCP_SET_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp->t1_timeout, dhcp); + dhcp->t1_renew_time = dhcp->t1_timeout; + } + /* set renewal period timer */ + if (dhcp->offered.offered_t2_rebind != 0xffffffffUL) { + DHCP_SET_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp->t2_timeout, dhcp); + dhcp->t2_rebind_time = dhcp->t2_timeout; + } + + /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ + if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { + dhcp->t1_timeout = 0; + } + + ip4_addr_t sn_mask; + + if (dhcp->flags & DHCP_FLAG_SUBNET_MASK_GIVEN) { + /* copy offered network mask */ + sn_mask.addr = dhcp->offered.offered_sn_mask.addr; + } else { + /* subnet mask not given, choose a safe subnet mask given the network class */ + const uint8_t first_octet = dhcp->offered.offered_ip_addr.addr & 0xFF; + if (first_octet <= 127) { + sn_mask.addr = 0xFF; + } else if (first_octet >= 192) { + sn_mask.addr = 0xFFFFFF; + } else { + sn_mask.addr = 0xFFFF; } + } + + ip4_addr_t gw_addr; + gw_addr.addr = dhcp->offered.offered_gw_addr.addr; + + dhcp_set_state(dhcp, dhcp::State::STATE_BOUND); + + netif_set_flags(netif::NETIF_FLAG_DHCP_OK); + netif_set_addr(dhcp->offered.offered_ip_addr, sn_mask, gw_addr); + + DEBUG_EXIT +} + +static void dhcp_rebind() { + DEBUG_ENTRY + + DEBUG_EXIT +} + +#if defined (CONFIG_NET_DHCP_USE_ACD) +static void dhcp_send_decline() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + dhcp_update_msg(dhcp::Type::DECLINE); + + uint32_t k = 6; + + s_dhcp_message.options[k++] = dhcp::Type::DECLINE; + + s_dhcp_message.options[k++] = dhcp::Options::OPTION_REQUESTED_IP; + s_dhcp_message.options[k++] = 0x04; + net::memcpy_ip(&s_dhcp_message.options[k], dhcp->offered.offered_ip_addr.addr); + k = k + 4; + s_dhcp_message.options[k++] = dhcp::Options::OPTION_END; + + udp_send(dhcp->nHandle, reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - dhcp::OPT_SIZE), network::IP4_BROADCAST, net::iana::IANA_PORT_DHCP_SERVER); + + DEBUG_EXIT +} + +static void dhcp_decline() { + DEBUG_ENTRY - return type; + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + dhcp_set_state(dhcp, dhcp::State::STATE_BACKING_OFF); + /* per section 4.4.4, broadcast DECLINE messages */ + dhcp_send_decline(); + + DEBUG_EXIT + return; +} + +static void dhcp_conflict_callback(net::acd::Callback callback) { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + assert(dhcp->state != dhcp::State::STATE_OFF); + + uint16_t msecs; + + switch (callback) { + case net::acd::Callback::ACD_IP_OK: + dhcp_bind(); + break; + case net::acd::Callback::ACD_RESTART_CLIENT: + /* wait 10s before restarting + * According to RFC2131 section 3.1 point 5: + * If the client detects that the address is already in use (e.g., through + * the use of ARP), the client MUST send a DHCPDECLINE message to the + * server and restarts the configuration process. The client SHOULD wait + * a minimum of ten seconds before restarting the configuration process to + * avoid excessive network traffic in case of looping. */ + dhcp_set_state (dhcp, dhcp::State::STATE_BACKING_OFF); + msecs = 10U * 1000U; + dhcp->request_timeout = static_cast((msecs + dhcp::DHCP_FINE_TIMER_MSECS - 1) / dhcp::DHCP_FINE_TIMER_MSECS); + break; + case net::acd::Callback::ACD_DECLINE: + /* remove IP address from interface + * (prevents routing from selecting this interface) */ + ip4_addr_t any; + any.addr = 0; + netif_set_addr(any, any, any); + /* Let the DHCP server know we will not use the address */ + dhcp_decline(); + netif_clear_flags(netif::NETIF_FLAG_DHCP_OK); + break; + default: + break; } +} - return -1; +static void dhcp_check() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + dhcp_set_state(dhcp, dhcp::State::STATE_CHECKING); + + acd_start(&dhcp->acd, dhcp->offered.offered_ip_addr); + + DEBUG_EXIT } +#endif -int dhcp_client(const char *pHostname) { +static void dhcp_discover() { DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); - auto bHaveIp = false; - int32_t retries = 20; +#if defined (CONFIG_NET_DHCP_USE_AUTOIP) + if (dhcp->tries >= DHCP_AUTOIP_COOP_TRIES) { + autoip_start(); + } +#endif - message_init(net::globals::macAddress); + dhcp->offered.offered_ip_addr.addr = 0; - auto nHandle = udp_begin(DHCP_PORT_CLIENT); + dhcp_set_state(dhcp, dhcp::State::STATE_SELECTING); - if (nHandle < 0) { - return -1; + send_discover(); + + if (dhcp->tries < 255) { + dhcp->tries++; } - net::globals::ipInfo.ip.addr = 0; - ip_set_ip(); + const auto msecs = DHCP_REQUEST_BACKOFF_SEQUENCE(dhcp->tries); + dhcp->request_timeout = static_cast((msecs + dhcp::DHCP_FINE_TIMER_MSECS - 1) / dhcp::DHCP_FINE_TIMER_MSECS); +} - while (!bHaveIp && (retries-- > 0)) { - DEBUG_PRINTF("retries=%d", retries); +static void dhcp_reboot() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); - send_discover(static_cast(nHandle), net::globals::macAddress); + dhcp_set_state(dhcp, dhcp::State::STATE_REBOOTING); - int type; + send_request(); - if ((type = parse_response(static_cast(nHandle), net::globals::macAddress)) < 0) { - continue; - } + if (dhcp->tries < 255) { + dhcp->tries++; + } - DEBUG_PRINTF("type=%d", type); + const auto msecs = static_cast(dhcp->tries < 10U ? dhcp->tries * 1000U : 10U * 1000U); + dhcp->request_timeout = static_cast((msecs + dhcp::DHCP_FINE_TIMER_MSECS - 1) / dhcp::DHCP_FINE_TIMER_MSECS); - if (type != DCHP_TYPE_OFFER) { - continue; - } + DEBUG_EXIT +} + +static void dhcp_select() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); - DEBUG_PRINTF(IPSTR, s_dhcp_server_ip[0],s_dhcp_server_ip[1],s_dhcp_server_ip[2],s_dhcp_server_ip[3]); + dhcp_set_state(dhcp, dhcp::State::STATE_REQUESTING); + + send_request(); + + if (dhcp->tries < 255) { + dhcp->tries++; + } + + const auto msecs = static_cast((dhcp->tries < 6 ? 1 << dhcp->tries : 60U) * 1000U); + dhcp->request_timeout = static_cast((msecs + dhcp::DHCP_FINE_TIMER_MSECS - 1) / dhcp::DHCP_FINE_TIMER_MSECS); +} + +static void dhcp_timeout() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + /* back-off period has passed, or server selection timed out */ + if ((dhcp->state == dhcp::State::STATE_BACKING_OFF) || (dhcp->state == dhcp::State::STATE_SELECTING)) { + dhcp_discover(); + /* receiving the requested lease timed out */ + } else if (dhcp->state == dhcp::State::STATE_REQUESTING) { + if (dhcp->tries <= 5) { + dhcp_select(); + } else { + dhcp_release_and_stop(); + dhcp_start(); + } + } else if (dhcp->state == dhcp::State::STATE_REBOOTING) { + if (dhcp->tries < REBOOT_TRIES) { + dhcp_reboot(); + } else { + dhcp_discover(); + } + } +} - _send_request(static_cast(nHandle), net::globals::macAddress, pHostname); +static void dhcp_t1_timeout() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if ((dhcp->state == dhcp::State::STATE_REQUESTING) + || (dhcp->state == dhcp::State::STATE_BOUND) + || (dhcp->state == dhcp::State::STATE_RENEWING)) { + /* just retry to renew - note that the rebind timer (t2) will + * eventually time-out if renew tries fail. */ + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ + dhcp_renew(); + /* Calculate next timeout */ + if (static_cast((dhcp->t2_timeout - dhcp->lease_used) / 2) >= DHCP_NEXT_TIMEOUT_THRESHOLD) { + dhcp->t1_renew_time = static_cast((dhcp->t2_timeout - dhcp->lease_used) / 2); + } + } +} - if ((type =parse_response(static_cast(nHandle), net::globals::macAddress)) < 0) { - continue; +static void dhcp_t2_timeout() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if ((dhcp->state == dhcp::State::STATE_REQUESTING) + || (dhcp->state == dhcp::State::STATE_BOUND) + || (dhcp->state == dhcp::State::STATE_RENEWING) + || (dhcp->state == dhcp::State::STATE_REBINDING)) { + /* just retry to rebind */ + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */ + dhcp_rebind(); + /* Calculate next timeout */ + if (static_cast((dhcp->t0_timeout - dhcp->lease_used) / 2) >= DHCP_NEXT_TIMEOUT_THRESHOLD) { + dhcp->t2_rebind_time = static_cast((dhcp->t0_timeout - dhcp->lease_used) / 2); } + } +} - DEBUG_PRINTF("type=%d", type); +void dhcp_coarse_tmr() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if ((dhcp != nullptr) && (dhcp->state != dhcp::State::STATE_OFF)) { + /* compare lease time to expire timeout */ + if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) { + /* this clients' lease time has expired */ + dhcp_release_and_stop(); + dhcp_start(); + /* timer is active (non zero), and triggers (zeroes) now? */ + } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) { + /* this clients' rebind timeout triggered */ + dhcp_t2_timeout(); + /* timer is active (non zero), and triggers (zeroes) now */ + } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) { + /* this clients' renewal timeout triggered */ + dhcp_t1_timeout(); + } + } +} - if (type == DCHP_TYPE_ACK) { - bHaveIp = true; - break; +static void dhcp_fine_tmr() { + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if (dhcp != nullptr) { + /* timer is active (non zero), and is about to trigger now */ + if (dhcp->request_timeout > 1) { + dhcp->request_timeout--; + } else if (dhcp->request_timeout == 1) { + dhcp->request_timeout--; + /* this client's request timeout triggered */ + dhcp_timeout(); } } +} + +static void dhcp_handle_offer(const dhcp::Message *const pResponse) { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if (dhcp->server_ip_addr.addr != 0) { + dhcp->request_timeout = 0; /* stop timer */ + dhcp->offered.offered_ip_addr.addr = net::memcpy_ip(pResponse->yiaddr); + DEBUG_PRINTF(IPSTR " -> " IPSTR, IP2STR(dhcp->server_ip_addr.addr), IP2STR(dhcp->offered.offered_ip_addr.addr)); + dhcp_select(); + } else { + DEBUG_PUTS("did not get server ID!"); + } + + DEBUG_EXIT +} - udp_end(DHCP_PORT_CLIENT); +static void dhcp_handle_ack(const dhcp::Message *const pResponse) { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); - if (bHaveIp) { - _pcast32 ip; + DEBUG_PRINTF("t0=%u, t1=%u, t2=%u", dhcp->offered.offered_t0_lease, dhcp->offered.offered_t1_renew, dhcp->offered.offered_t2_rebind); - memcpy(ip.u8, s_dhcp_allocated_ip, IPv4_ADDR_LEN); - net::globals::ipInfo.ip.addr = ip.u32; + if (dhcp->offered.offered_t1_renew == 0) { + /* calculate safe periods for renewal */ + dhcp->offered.offered_t1_renew = dhcp->offered.offered_t0_lease / 2; + } - memcpy(ip.u8, s_dhcp_allocated_gw, IPv4_ADDR_LEN); - net::globals::ipInfo.gw.addr = ip.u32; + if (dhcp->offered.offered_t2_rebind == 0) { + /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/ + dhcp->offered.offered_t2_rebind = (dhcp->offered.offered_t0_lease * 7U) / 8U; + } + + dhcp->offered.offered_ip_addr.addr = net::memcpy_ip(pResponse->yiaddr); - memcpy(ip.u8, s_dhcp_allocated_netmask, IPv4_ADDR_LEN); - net::globals::ipInfo.netmask.addr = ip.u32; + if (dhcp->offered.offered_sn_mask.addr != 0) { + dhcp->flags |= DHCP_FLAG_SUBNET_MASK_GIVEN; + } else { + dhcp->flags &= ~DHCP_FLAG_SUBNET_MASK_GIVEN; } + DEBUG_PRINTF("t0=%u, t1=%u, t2=%u", dhcp->offered.offered_t0_lease, dhcp->offered.offered_t1_renew, dhcp->offered.offered_t2_rebind); DEBUG_EXIT - return bHaveIp ? 0 : -2; } -void dhcp_client_release() { +static void dhcp_handle_nak() { DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + // Change to a defined state - set this before assigning the address + // to ensure the callback can use dhcp_supplied_address() + dhcp_set_state(dhcp, dhcp::State::STATE_BACKING_OFF); + // remove IP address from interface (must no longer be used, as per RFC2131) + ip4_addr_t any; + any.addr = 0; + netif_set_addr(any, any, any); + // We can immediately restart discovery + dhcp_discover(); - auto nHandle = udp_begin(DHCP_PORT_CLIENT); + DEBUG_EXIT +} - if (nHandle < 0) { - console_error("dhcp_client_release\n"); +bool dhcp_start() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if (dhcp == nullptr) { + dhcp = new (struct dhcp::Dhcp); + assert(dhcp != nullptr); + globals::netif_default.dhcp = dhcp; + + nTimerId = Hardware::Get()->SoftwareTimerAdd(dhcp::DHCP_FINE_TIMER_MSECS, dhcp_fine_tmr); + assert(nTimerId >= 0); + } + + memset(dhcp, 0, sizeof(struct dhcp::Dhcp)); + dhcp->nHandle = udp_begin(net::iana::IANA_PORT_DHCP_CLIENT); + +#ifndef NDEBUG + if (dhcp->nHandle < 0) { + console_error("DHCP Start\n"); + DEBUG_EXIT + return false; + } +#endif + + message_init(); + +#if defined (CONFIG_NET_DHCP_USE_ACD) + acd_add(&dhcp->acd, dhcp_conflict_callback); +#endif + + if (!netif_is_link_up()) { + dhcp_set_state(dhcp, dhcp::State::STATE_INIT); + return false; + } + + dhcp_discover(); + + DEBUG_EXIT + return true; +} + +void dhcp_release_and_stop() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + + if (dhcp == nullptr) { + DEBUG_EXIT return; } - uint32_t k = 6; + if (dhcp->state == dhcp::State::STATE_OFF) { + return; + } - s_dhcp_message.options[k++] = DCHP_TYPE_RELEASE; + ip4_addr_t server_ip_addr; - s_dhcp_message.options[k++] = OPTIONS_SERVER_IDENTIFIER; - s_dhcp_message.options[k++] = 0x04; - s_dhcp_message.options[k++] = s_dhcp_server_ip[0]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[1]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[2]; - s_dhcp_message.options[k++] = s_dhcp_server_ip[3]; + server_ip_addr.addr = dhcp->server_ip_addr.addr; + + /* clean old DHCP offer */ + dhcp->server_ip_addr.addr = 0; + memset(&dhcp->offered, 0, sizeof(struct dhcp::Dhcp::Offered)); + dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0; + + if (dhcp_supplied_address()) { + dhcp_set_state(dhcp, dhcp::State::STATE_OFF); + + dhcp_send_release(server_ip_addr.addr); + + udp_end(net::iana::IANA_PORT_DHCP_CLIENT); + + /* remove IP address from interface (prevents routing from selecting this interface) */ + ip4_addr_t any; + any.addr = 0; + netif_set_addr(any, any, any); + } + +#if defined (CONFIG_NET_DHCP_USE_ACD) + acd_remove(&dhcp->acd); +#endif + + delete reinterpret_cast(globals::netif_default.dhcp); + globals::netif_default.dhcp = nullptr; +} + +void dhcp_network_changed_link_up() { + DEBUG_ENTRY + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); - s_dhcp_message.options[k++] = OPTIONS_END_OPTION; + if (dhcp == nullptr) { + DEBUG_EXIT + return; + } + + switch (dhcp->state) { + case dhcp::State::STATE_REBINDING: + case dhcp::State::STATE_RENEWING: + case dhcp::State::STATE_BOUND: + case dhcp::State::STATE_REBOOTING: + dhcp->tries = 0; + dhcp_reboot(); + break; + case dhcp::State::STATE_OFF: + break; + default: + dhcp->tries = 0; + dhcp_discover(); + break; + } +} + +void dhcp_process(const dhcp::Message *const pResponse, const uint32_t nSize) { + DEBUG_ENTRY + + assert(pResponse != nullptr); + + uint8_t msg_type = 0; + uint8_t opt_len = 0; - udp_send(static_cast(nHandle), reinterpret_cast(&s_dhcp_message), static_cast(k + sizeof(dhcp::Message) - DHCP_OPT_SIZE), IP_BROADCAST, DHCP_PORT_SERVER); - udp_end(DHCP_PORT_CLIENT); + auto *dhcp = reinterpret_cast(globals::netif_default.dhcp); + assert(dhcp != nullptr); + + memset(&dhcp->offered, 0, sizeof(struct dhcp::Dhcp::Offered)); + + dhcp->server_ip_addr.addr = 0; + + const auto *p = reinterpret_cast(pResponse); + p = p + sizeof(dhcp::Message) - dhcp::OPT_SIZE + 4; + auto *e = p + nSize; + + while (p < e) { + switch (*p) { + case dhcp::Options::OPTION_END: + p = e; + break; + case dhcp::Options::OPTION_PAD_OPTION: + p++; + break; + case dhcp::Options::OPTION_MESSAGE_TYPE: + p++; + p++; + msg_type = *p++; + break; + case dhcp::Options::OPTION_SUBNET_MASK: + p++; + p++; + dhcp->offered.offered_sn_mask.addr = net::memcpy_ip(p); + p = p + 4; + break; + case dhcp::Options::OPTION_ROUTER: + p++; + p++; + dhcp->offered.offered_gw_addr.addr = net::memcpy_ip(p); + p = p + 4; + break; + case dhcp::Options::OPTION_SERVER_IDENTIFIER: + p++; + p++; + dhcp->server_ip_addr.addr = net::memcpy_ip(p); + p += 4; + break; + case dhcp::Options::OPTION_LEASE_TIME: + p++; + p++; + dhcp->offered.offered_t0_lease = __builtin_bswap32(net::memcpy_ip(p)); + p += 4; + break; + case dhcp::Options::OPTION_DHCP_T1_VALUE: + p++; + p++; + dhcp->offered.offered_t1_renew = __builtin_bswap32(net::memcpy_ip(p)); + p += 4; + break; + case dhcp::Options::OPTION_DHCP_T2_VALUE: + p++; + p++; + dhcp->offered.offered_t2_rebind = __builtin_bswap32(net::memcpy_ip(p)); + p += 4; + break; + default: + p++; + opt_len = *p++; + p += opt_len; + break; + } + } + + if (msg_type == dhcp::Type::OFFER) { + dhcp->offered.offered_ip_addr.addr = net::memcpy_ip(pResponse->yiaddr); + } + + DEBUG_PRINTF("msg_type=%u", msg_type); + + if (msg_type == dhcp::Type::ACK) { + /* in requesting state or just reconnected to the network? */ + if ((dhcp->state == dhcp::State::STATE_REQUESTING) || + (dhcp->state == dhcp::State::STATE_REBOOTING)) { + dhcp_handle_ack(pResponse); +#if defined (CONFIG_NET_DHCP_USE_ACD) + dhcp_check(); +#else + dhcp_bind(); +#endif + } + else if ((dhcp->state == dhcp::State::STATE_REBINDING) || + (dhcp->state == dhcp::State::STATE_RENEWING)) { + dhcp_handle_ack(pResponse); + dhcp_bind(); + } + } + else if ((msg_type == dhcp::Type::NAK) && + ((dhcp->state == dhcp::State::STATE_REBOOTING) || (dhcp->state == dhcp::State::STATE_REQUESTING) || + (dhcp->state == dhcp::State::STATE_REBINDING) || (dhcp->state == dhcp::State::STATE_RENEWING ))) { + dhcp_handle_nak(); + } + else if ((msg_type == dhcp::Type::OFFER) && (dhcp->state == dhcp::State::STATE_SELECTING)) { + dhcp_handle_offer(pResponse); + } DEBUG_EXIT } +} // namespace net diff --git a/lib-network/src/net/icmp.cpp b/lib-network/src/net/icmp.cpp old mode 100644 new mode 100755 index 17afb63..51d8b23 --- a/lib-network/src/net/icmp.cpp +++ b/lib-network/src/net/icmp.cpp @@ -2,7 +2,7 @@ * @file icmp.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,39 +23,48 @@ * THE SOFTWARE. */ +#if defined (DEBUG_NET_ICMP) +# undef NDEBUG +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + #include #include -#include "net.h" -#include "net_private.h" - #include "../../config/net_config.h" -namespace net { -namespace globals { -extern struct IpInfo ipInfo; -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net +#include "net_memcpy.h" +#include "net_private.h" -typedef union pcast32 { - uint32_t u32; - uint8_t u8[4]; -} _pcast32; +#include "net/protocol/icmp.h" +#include "debug.h" + +namespace net { __attribute__((hot)) void icmp_handle(struct t_icmp *p_icmp) { if (p_icmp->icmp.type == ICMP_TYPE_ECHO) { if (p_icmp->icmp.code == ICMP_CODE_ECHO) { // Ethernet - memcpy(p_icmp->ether.dst, p_icmp->ether.src, ETH_ADDR_LEN); - memcpy(p_icmp->ether.src, net::globals::macAddress, ETH_ADDR_LEN); - + std::memcpy(p_icmp->ether.dst, p_icmp->ether.src, ETH_ADDR_LEN); + std::memcpy(p_icmp->ether.src, globals::netif_default.hwaddr, ETH_ADDR_LEN); // IPv4 p_icmp->ip4.id = static_cast(~p_icmp->ip4.id); - uint8_t dst[IPv4_ADDR_LEN]; - memcpy(dst, p_icmp->ip4.dst, IPv4_ADDR_LEN); - memcpy(p_icmp->ip4.dst, p_icmp->ip4.src, IPv4_ADDR_LEN); - memcpy(p_icmp->ip4.src, dst, IPv4_ADDR_LEN); + + const auto nIpDestination = net::memcpy_ip(p_icmp->ip4.dst); + + std::memcpy(p_icmp->ip4.dst, p_icmp->ip4.src, IPv4_ADDR_LEN); + + if (nIpDestination == globals::netif_default.secondary_ip.addr) { + net::memcpy_ip(p_icmp->ip4.src, globals::netif_default.secondary_ip.addr); + } else { + net::memcpy_ip(p_icmp->ip4.src, globals::netif_default.ip.addr); + } + p_icmp->ip4.chksum = 0; #if !defined (CHECKSUM_BY_HARDWARE) p_icmp->ip4.chksum = net_chksum(reinterpret_cast(&p_icmp->ip4), 20); //TODO @@ -66,7 +75,8 @@ __attribute__((hot)) void icmp_handle(struct t_icmp *p_icmp) { #if !defined (CHECKSUM_BY_HARDWARE) p_icmp->icmp.checksum = net_chksum(reinterpret_cast(&p_icmp->ip4), static_cast(__builtin_bswap16(p_icmp->ip4.len))); #endif - emac_eth_send(reinterpret_cast(p_icmp), (sizeof(struct ether_header) + __builtin_bswap16(p_icmp->ip4.len))); + emac_eth_send(reinterpret_cast(p_icmp), static_cast(sizeof(struct ether_header) + __builtin_bswap16(p_icmp->ip4.len))); } } } +} // namespace net diff --git a/lib-network/src/net/igmp.cpp b/lib-network/src/net/igmp.cpp index ac58a96..35456ee 100644 --- a/lib-network/src/net/igmp.cpp +++ b/lib-network/src/net/igmp.cpp @@ -2,7 +2,7 @@ * @file igmp.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,20 +23,44 @@ * THE SOFTWARE. */ +#if defined (DEBUG_NET_IGMP) +# undef NDEBUG +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + #include -#include +#include #include +#include + +#include "../../config/net_config.h" #include "net.h" +#include "netif.h" +#include "net/igmp.h" +#include "net/protocol/igmp.h" + +#include "net_memcpy.h" #include "net_private.h" -#include "../../config/net_config.h" +#include "hardware.h" + +#include "debug.h" /* * https://www.rfc-editor.org/rfc/rfc2236.html * Internet Group Management Protocol, Version 2 */ +namespace net { +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + enum State { NON_MEMBER, DELAYING_MEMBER, IDLE_MEMBER }; @@ -57,23 +81,68 @@ static struct t_igmp s_leave SECTION_NETWORK ALIGNED; static uint8_t s_multicast_mac[ETH_ADDR_LEN] SECTION_NETWORK ALIGNED; static struct t_group_info s_groups[IGMP_MAX_JOINS_ALLOWED] SECTION_NETWORK ALIGNED; static uint16_t s_id SECTION_NETWORK ALIGNED; +static int32_t nTimerId; -namespace net { -namespace globals { -extern struct IpInfo ipInfo; -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net +void igmp_set_ip() { + net::memcpy_ip(s_report.ip4.src, net::globals::netif_default.ip.addr); + net::memcpy_ip(s_leave.ip4.src, net::globals::netif_default.ip.addr); +} -static void _send_report(uint32_t nGroupAddress); +static void igmp_send_report(const uint32_t nGroupAddress) { + DEBUG_ENTRY + _pcast32 multicast_ip; -void igmp_set_ip() { - _pcast32 src; + multicast_ip.u32 = nGroupAddress; + + s_multicast_mac[3] = multicast_ip.u8[1] & 0x7F; + s_multicast_mac[4] = multicast_ip.u8[2]; + s_multicast_mac[5] = multicast_ip.u8[3]; - src.u32 = net::globals::ipInfo.ip.addr; + DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(nGroupAddress),MAC2STR(s_multicast_mac)); - memcpy(s_report.ip4.src, src.u8, IPv4_ADDR_LEN); - memcpy(s_leave.ip4.src, src.u8, IPv4_ADDR_LEN); + // Ethernet + std::memcpy(s_report.ether.dst, s_multicast_mac, ETH_ADDR_LEN); + // IPv4 + s_report.ip4.id = s_id; + std::memcpy(s_report.ip4.dst, multicast_ip.u8, IPv4_ADDR_LEN); + s_report.ip4.chksum = 0; + s_report.ip4.chksum = net_chksum(reinterpret_cast(&s_report.ip4), 24); //TODO + // IGMP + std::memcpy(s_report.igmp.report.igmp.group_address, multicast_ip.u8, IPv4_ADDR_LEN); + s_report.igmp.report.igmp.checksum = 0; + s_report.igmp.report.igmp.checksum = net_chksum(reinterpret_cast(&s_report.ip4), IPv4_IGMP_REPORT_HEADERS_SIZE); + + emac_eth_send(reinterpret_cast(&s_report), IGMP_REPORT_PACKET_SIZE); + + s_id++; + + DEBUG_EXIT +} + +static void igmp_start_timer(struct t_group_info &group, const uint32_t max_time) { + group.nTimer = (max_time > 2 ? (random() % max_time) : 1); + + if (group.nTimer == 0) { + group.nTimer = 1; + } +} + +static void igmp_timeout(struct t_group_info &group) { + if ((group.state == DELAYING_MEMBER) && (group.nGroupAddress != 0x010000e0)) { //FIXME all-systems + group.state = IDLE_MEMBER; + igmp_send_report(group.nGroupAddress); + } +} + +static void igmp_timer() { + for (auto &group : s_groups) { + if (group.nTimer > 0) { + group.nTimer--; + if (group.nTimer == 0) { + igmp_timeout(group); + } + } + } } void __attribute__((cold)) igmp_init() { @@ -84,7 +153,7 @@ void __attribute__((cold)) igmp_init() { s_multicast_mac[2] = 0x5E; // Ethernet - memcpy(s_report.ether.src, net::globals::macAddress, ETH_ADDR_LEN); + std::memcpy(s_report.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); s_report.ether.type = __builtin_bswap16(ETHER_TYPE_IPv4); // IPv4 @@ -108,7 +177,7 @@ void __attribute__((cold)) igmp_init() { s_leave.ether.dst[3] = 0x00; s_leave.ether.dst[4] = 0x00; s_leave.ether.dst[5] = 0x02; - memcpy(s_leave.ether.src, net::globals::macAddress, ETH_ADDR_LEN); + std::memcpy(s_leave.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); s_leave.ether.type = __builtin_bswap16(ETHER_TYPE_IPv4); // IPv4 @@ -129,14 +198,8 @@ void __attribute__((cold)) igmp_init() { s_leave.igmp.report.igmp.type = IGMP_TYPE_LEAVE; s_leave.igmp.report.igmp.max_resp_time = 0; - /* - * https://tldp.org/HOWTO/Multicast-HOWTO-2.html - * 224.0.0.1 is the all-hosts group. If you ping that group, - * all multicast capable hosts on the network should answer, - * as every multicast capable host must join that group - * at start-up on all it's multicast capable interfaces. - */ - _send_report(0x010000e0); + nTimerId = Hardware::Get()->SoftwareTimerAdd(IGMP_TMR_INTERVAL, igmp_timer); + assert(nTimerId >= 0); } void __attribute__((cold)) igmp_shutdown() { @@ -153,43 +216,8 @@ void __attribute__((cold)) igmp_shutdown() { DEBUG_EXIT } -static void _send_report(const uint32_t nGroupAddress) { - DEBUG_ENTRY - _pcast32 multicast_ip; - - multicast_ip.u32 = nGroupAddress; - - s_multicast_mac[3] = multicast_ip.u8[1] & 0x7F; - s_multicast_mac[4] = multicast_ip.u8[2]; - s_multicast_mac[5] = multicast_ip.u8[3]; - - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(nGroupAddress),MAC2STR(s_multicast_mac)); - - // Ethernet - memcpy(s_report.ether.dst, s_multicast_mac, ETH_ADDR_LEN); - // IPv4 - s_report.ip4.id = s_id; - memcpy(s_report.ip4.dst, multicast_ip.u8, IPv4_ADDR_LEN); - s_report.ip4.chksum = 0; - s_report.ip4.chksum = net_chksum(reinterpret_cast(&s_report.ip4), 24); //TODO - // IGMP - memcpy(s_report.igmp.report.igmp.group_address, multicast_ip.u8, IPv4_ADDR_LEN); - s_report.igmp.report.igmp.checksum = 0; - s_report.igmp.report.igmp.checksum = net_chksum(reinterpret_cast(&s_report.ip4), IPv4_IGMP_REPORT_HEADERS_SIZE); - - emac_eth_send(reinterpret_cast(&s_report), IGMP_REPORT_PACKET_SIZE); - - s_id++; - - DEBUG_EXIT -} - -static void _send_leave(const uint32_t nGroupAddress) { +static void igmp_send_leave(const uint32_t nGroupAddress) { DEBUG_ENTRY - _pcast32 multicast_ip; - - multicast_ip.u32 = nGroupAddress; - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(nGroupAddress), MAC2STR(s_multicast_mac)); // IPv4 @@ -199,7 +227,7 @@ static void _send_leave(const uint32_t nGroupAddress) { s_leave.ip4.chksum = net_chksum(reinterpret_cast(&s_leave.ip4), 24); //TODO #endif // IGMP - memcpy(s_leave.igmp.report.igmp.group_address, multicast_ip.u8, IPv4_ADDR_LEN); + net::memcpy_ip(s_leave.igmp.report.igmp.group_address, nGroupAddress); s_leave.igmp.report.igmp.checksum = 0; #if !defined (CHECKSUM_BY_HARDWARE) s_leave.igmp.report.igmp.checksum = net_chksum(reinterpret_cast(&s_leave.ip4), IPv4_IGMP_REPORT_HEADERS_SIZE); @@ -251,16 +279,11 @@ __attribute__((hot)) void igmp_handle(struct t_igmp *p_igmp) { DEBUG_EXIT } -void igmp_timer() { - for (auto& group : s_groups) { - if ((group.state == DELAYING_MEMBER) && (group.nTimer > 0)) { - group.nTimer--; - - if (group.nTimer == 0) { - _send_report(group.nGroupAddress); - group.state = IDLE_MEMBER; - } - } +static void igmp_delaying_member(struct t_group_info &group, const uint32_t maxresp) { + if ((group.state == IDLE_MEMBER) + || ((group.state == DELAYING_MEMBER) && ((group.nTimer == 0) || (maxresp < group.nTimer)))) { + igmp_start_timer(group, maxresp); + group.state = DELAYING_MEMBER; } } @@ -286,7 +309,7 @@ void igmp_join(uint32_t nGroupAddress) { s_groups[i].state = DELAYING_MEMBER; s_groups[i].nTimer = 2; // TODO - _send_report(nGroupAddress); + igmp_send_report(nGroupAddress); DEBUG_EXIT return; @@ -306,7 +329,7 @@ void igmp_leave(uint32_t nGroupAddress) { for (auto& group : s_groups) { if (group.nGroupAddress == nGroupAddress) { - _send_leave(group.nGroupAddress); + igmp_send_leave(group.nGroupAddress); group.nGroupAddress = 0; group.state = NON_MEMBER; @@ -324,4 +347,10 @@ void igmp_leave(uint32_t nGroupAddress) { DEBUG_EXIT } +void igmp_report_groups() { + for (auto& group : s_groups) { + igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + } +} +} // namespace net // <--- diff --git a/lib-network/src/net/ip.cpp b/lib-network/src/net/ip.cpp index e697459..b2f3c6b 100644 --- a/lib-network/src/net/ip.cpp +++ b/lib-network/src/net/ip.cpp @@ -2,7 +2,7 @@ * @file ip.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,13 +23,26 @@ * THE SOFTWARE. */ +#if defined (DEBUG_NET_IP) +# undef NDEBUG +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + #include +#include "../../config/net_config.h" + #include "net.h" #include "net_private.h" -#include "../../config/net_config.h" +#include "debug.h" +namespace net { void ip_set_ip() { udp_set_ip(); igmp_set_ip(); @@ -40,16 +53,9 @@ void __attribute__((cold)) ip_init() { udp_init(); igmp_init(); +#if defined (ENABLE_HTTPD) tcp_init(); - - DEBUG_EXIT -} - -void __attribute__((cold)) ip_shutdown() { - DEBUG_ENTRY - - tcp_shutdown(); - igmp_shutdown(); +#endif DEBUG_EXIT } @@ -85,3 +91,4 @@ __attribute__((hot)) void ip_handle(struct t_ip4 *p_ip4) { break; } } +} // namespace net diff --git a/lib-network/src/net/net.cpp b/lib-network/src/net/net.cpp old mode 100644 new mode 100755 index 0afe1e2..ae8402e --- a/lib-network/src/net/net.cpp +++ b/lib-network/src/net/net.cpp @@ -2,7 +2,7 @@ * @file net.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,200 +23,160 @@ * THE SOFTWARE. */ +#if defined (DEBUG_NET_NET) +# if defined (NDEBUG) +# undef NDEBUG +# endif +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + #include #include +#include "../../config/net_config.h" + #include "net.h" #include "net_private.h" -#include "net_packets.h" -#include "net_debug.h" -#include "../../config/net_config.h" +#include "netif.h" +#include "net/acd.h" +#include "net/dhcp.h" + +#include "debug.h" + +static struct net::acd::Acd s_acd; + +namespace network { +__attribute__((weak)) void mdns_shutdown() {} +} // namespace network namespace net { namespace globals { -struct IpInfo ipInfo ALIGNED; uint32_t nBroadcastMask; uint32_t nOnNetworkMask; -uint8_t macAddress[ETH_ADDR_LEN] ALIGNED; } // namespace globals -} // namespace net - -static uint8_t *s_p; -static bool s_isDhcp = false; - -static void refresh_and_init(struct IpInfo *pIpInfo, bool doInit) { - net::globals::ipInfo.broadcast_ip.addr = net::globals::ipInfo.ip.addr | ~net::globals::ipInfo.netmask.addr; - - net::globals::nBroadcastMask = ~(net::globals::ipInfo.netmask.addr); - net::globals::nOnNetworkMask = net::globals::ipInfo.ip.addr & net::globals::ipInfo.netmask.addr; - - if (doInit) { - arp_init(); - ip_set_ip(); - } - - const auto *pSrc = reinterpret_cast(&net::globals::ipInfo); - auto *pDst = reinterpret_cast(pIpInfo); - - memcpy(pDst, pSrc, sizeof(struct IpInfo)); -} - -void set_secondary_ip() { - net::globals::ipInfo.ip.addr = net::globals::ipInfo.secondary_ip.addr; - net::globals::ipInfo.netmask.addr = 255; - net::globals::ipInfo.gw.addr = net::globals::ipInfo.ip.addr; -} +#if defined (CONFIG_ENET_ENABLE_PTP) +void ptp_init(); +void ptp_handle(const uint8_t *, const uint32_t); +#endif -void __attribute__((cold)) net_init(const uint8_t *const pMacAddress, struct IpInfo *pIpInfo, const char *pHostname, bool *bUseDhcp, bool *isZeroconfUsed) { +void net_shutdown() { DEBUG_ENTRY - memcpy(net::globals::macAddress, pMacAddress, ETH_ADDR_LEN); - - const auto *pSrc = reinterpret_cast(pIpInfo); - auto *pDst = reinterpret_cast(&net::globals::ipInfo); - - memcpy(pDst, pSrc, sizeof(struct IpInfo)); - - net::globals::ipInfo.secondary_ip.addr = 2 - + ((static_cast(net::globals::macAddress[3])) << 8) - + ((static_cast(net::globals::macAddress[4])) << 16) - + ((static_cast(net::globals::macAddress[5])) << 24); - - - if (net::globals::ipInfo.ip.addr == 0) { - set_secondary_ip(); - } - /* - * The macAddress is set - */ - ip_init(); - - *isZeroconfUsed = false; - - if (*bUseDhcp) { - if (dhcp_client(pHostname) < 0) { - *bUseDhcp = false; - DEBUG_PUTS("DHCP Client failed"); - *isZeroconfUsed = rfc3927(); - } - } - - refresh_and_init(pIpInfo, true); - - s_isDhcp = *bUseDhcp; - - if (!arp_do_probe()) { - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(net::globals::ipInfo.ip.addr), MAC2STR(net::globals::macAddress)); - arp_send_announcement(); - } else { - console_error("IP Conflict!\n"); - } + net::netif_set_link_down(); DEBUG_EXIT } -void __attribute__((cold)) net_shutdown() { - ip_shutdown(); +static void primary_ip_conflict_callback(net::acd::Callback callback) { + auto &netif = net::globals::netif_default; - if (s_isDhcp) { - dhcp_client_release(); + switch (callback) { + case net::acd::Callback::ACD_IP_OK: + if (s_acd.ipaddr.addr == netif.secondary_ip.addr) { + net_set_secondary_ip(); + } else { + net::netif_set_ipaddr(s_acd.ipaddr); + } + dhcp_inform(); + netif_set_flags(netif::NETIF_FLAG_STATICIP_OK); + break; + case net::acd::Callback::ACD_RESTART_CLIENT: + break; + case net::acd::Callback::ACD_DECLINE: + netif_clear_flags(netif::NETIF_FLAG_STATICIP_OK); + break; + default: + break; } } -void net_set_ip(struct IpInfo *pIpInfo) { - net::globals::ipInfo.ip.addr = pIpInfo->ip.addr; +void net_set_primary_ip(const ip4_addr_t ipaddr) { + auto &netif = net::globals::netif_default; - if (net::globals::ipInfo.ip.addr == 0) { - set_secondary_ip(); - } + net::dhcp_release_and_stop(); - refresh_and_init(pIpInfo, true); + acd_add(&s_acd, primary_ip_conflict_callback); - if (!arp_do_probe()) { - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(net::globals::ipInfo.ip.addr), MAC2STR(net::globals::macAddress)); - arp_send_announcement(); + if (ipaddr.addr == 0) { + acd_start(&s_acd, netif.secondary_ip); } else { - console_error("IP Conflict!\n"); + acd_start(&s_acd, ipaddr); } } -void net_set_netmask(struct IpInfo *pIpInfo) { - net::globals::ipInfo.netmask.addr = pIpInfo->netmask.addr; - - refresh_and_init(pIpInfo, false); -} - -void net_set_gw(struct IpInfo *pIpInfo) { - net::globals::ipInfo.gw.addr = pIpInfo->gw.addr; - - ip_set_ip(); +void net_set_secondary_ip() { + auto &netif = net::globals::netif_default; + ip4_addr_t netmask; + netmask.addr = 255; + net::netif_set_addr(netif.secondary_ip, netmask, netif.secondary_ip); } -bool net_set_dhcp(struct IpInfo *pIpInfo, const char *const pHostname, bool *isZeroconfUsed) { - bool isDhcp = false; - *isZeroconfUsed = false; - - if (dhcp_client(pHostname) < 0) { - DEBUG_PUTS("DHCP Client failed"); - *isZeroconfUsed = rfc3927(); - } else { - isDhcp = true; - } +void __attribute__((cold)) net_init(const net::Link link, ip4_addr_t ipaddr, ip4_addr_t netmask, ip4_addr_t gw, bool &bUseDhcp) { + DEBUG_ENTRY + globals::netif_default.secondary_ip.addr = 2 + + ((static_cast(globals::netif_default.hwaddr[3])) << 8) + + ((static_cast(globals::netif_default.hwaddr[4])) << 16) + + ((static_cast(globals::netif_default.hwaddr[5])) << 24); - refresh_and_init(pIpInfo, true); + net::arp_init(); + ip_init(); - s_isDhcp = isDhcp; + if (net::Link::STATE_UP == link) { + net::netif_set_flags(net::netif::NETIF_FLAG_LINK_UP); - if (!arp_do_probe()) { - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(net::globals::ipInfo.ip.addr), MAC2STR(net::globals::macAddress)); - arp_send_announcement(); + if (bUseDhcp) { + dhcp_start(); + } else { +// if (ipaddr.addr == 0) { +// net_set_secondary_ip(); +// } else { +// net::netif_set_addr(ipaddr, netmask, gw); +// } +// dhcp_inform(); + if (ipaddr.addr != 0) { + net::netif_set_netmask(netmask); + net::netif_set_gw(gw); + } + net_set_primary_ip(ipaddr); + } } else { - console_error("IP Conflict!\n"); + net::netif_clear_flags(net::netif::NETIF_FLAG_LINK_UP); } - return isDhcp; -} - -void net_dhcp_release() { - dhcp_client_release(); - s_isDhcp = false; -} - -bool net_set_zeroconf(struct IpInfo *pIpInfo) { - const auto b = rfc3927(); - - if (b) { - refresh_and_init(pIpInfo, true); - - s_isDhcp = false; - - DEBUG_PRINTF(IPSTR " " MACSTR, IP2STR(net::globals::ipInfo.ip.addr), MAC2STR(net::globals::macAddress)); - arp_send_announcement(); +#if defined (CONFIG_ENET_ENABLE_PTP) + net::ptp_init(); +#endif - return true; - } - - DEBUG_PUTS("Zeroconf failed"); - return false; + DEBUG_EXIT } __attribute__((hot)) void net_handle() { + uint8_t *s_p; const auto nLength = emac_eth_recv(&s_p); if (__builtin_expect((nLength > 0), 0)) { const auto *const eth = reinterpret_cast(s_p); - if (eth->type == __builtin_bswap16(ETHER_TYPE_IPv4)) { - ip_handle(reinterpret_cast(s_p)); - } else if (eth->type == __builtin_bswap16(ETHER_TYPE_ARP)) { - arp_handle(reinterpret_cast(s_p)); - } else { - DEBUG_PRINTF("type %04x is not implemented", __builtin_bswap16(eth->type)); - } +#if defined (CONFIG_ENET_ENABLE_PTP) + if (eth->type == __builtin_bswap16(ETHER_TYPE_PTP)) { + net::ptp_handle(const_cast(s_p), nLength); + } else +#endif + if (eth->type == __builtin_bswap16(ETHER_TYPE_IPv4)) { + ip_handle(reinterpret_cast(s_p)); + } else if (eth->type == __builtin_bswap16(ETHER_TYPE_ARP)) { + net::arp_handle(reinterpret_cast(s_p)); + } else { + DEBUG_PRINTF("type %04x is not implemented", __builtin_bswap16(eth->type)); + } emac_free_pkt(); } - - net_timers_run(); } +} // namespace net diff --git a/lib-network/src/net/net_chksum.cpp b/lib-network/src/net/net_chksum.cpp index 75fcb51..408ebaa 100644 --- a/lib-network/src/net/net_chksum.cpp +++ b/lib-network/src/net/net_chksum.cpp @@ -2,7 +2,7 @@ * @file net_chksum.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,10 +23,13 @@ * THE SOFTWARE. */ -#include +#pragma GCC push_options +#pragma GCC optimize ("O2") +#pragma GCC optimize ("no-tree-loop-distribute-patterns") -#include "net_private.h" +#include +namespace net { uint16_t net_chksum(const void *data, uint32_t len) { auto *ptr = reinterpret_cast(data); uint32_t sum = 0; @@ -49,3 +52,4 @@ uint16_t net_chksum(const void *data, uint32_t len) { return static_cast(~sum); } +} // namespace net diff --git a/lib-network/src/net/net_memcpy.h b/lib-network/src/net/net_memcpy.h index c7a70bd..ca4f1d5 100644 --- a/lib-network/src/net/net_memcpy.h +++ b/lib-network/src/net/net_memcpy.h @@ -2,7 +2,7 @@ * @file net_memcpy.h * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,19 +27,23 @@ #include #include -inline void *net_memcpy(void *__restrict__ dest, void const *__restrict__ src, size_t n) { - auto *plDst = reinterpret_cast(dest); - auto const *plSrc = reinterpret_cast(src); +#include "net/protocol/ip4.h" - if (((reinterpret_cast(src) & 0x3) == 0) && ((reinterpret_cast(dest) & 0x3) == 0)) { - while (n >= 4) { +namespace net { +inline void* memcpy(void *__restrict__ dest, void const *__restrict__ src, size_t n) { + auto *plDst = reinterpret_cast(dest); + auto const *plSrc = reinterpret_cast(src); + + if (((reinterpret_cast(src) & (sizeof(uintptr_t) - 1)) == 0) + && ((reinterpret_cast(dest) & (sizeof(uintptr_t) - 1)) == 0)) { + while (n >= sizeof(uintptr_t)) { *plDst++ = *plSrc++; - n -= 4; + n -= sizeof(uintptr_t); } } - auto *pcDst = reinterpret_cast(plDst); - auto const *pcSrc = reinterpret_cast(plSrc); + auto *pcDst = reinterpret_cast(plDst); + auto const *pcSrc = reinterpret_cast(plSrc); while (n--) { *pcDst++ = *pcSrc++; @@ -48,4 +52,64 @@ inline void *net_memcpy(void *__restrict__ dest, void const *__restrict__ src, s return dest; } +inline void memcpy_ip(uint8_t *pIpAddress, const uint32_t nIpAddress) { +#ifdef __ARM_ARCH_7A__ + // Ensure destination pointer is aligned + if ((reinterpret_cast(pIpAddress) & ((sizeof(uint32_t) - 1))) == 0) { + // Destination pointer is already aligned, perform fast copy + *reinterpret_cast(pIpAddress) = nIpAddress; + } else +#endif + { // Destination pointer is not aligned, copy byte by byte + typedef union pcast32 { + uint32_t u32; + uint8_t u8[4]; + } _pcast32; + + _pcast32 src; + src.u32 = nIpAddress; +#ifdef __ARM_ARCH_7A__ + volatile auto *pSrc = src.u8; + volatile auto *pDst = pIpAddress; +#else + auto *pSrc = src.u8; + auto *pDst = pIpAddress; +#endif + for (uint32_t i = 0; i < IPv4_ADDR_LEN; i++) { + pDst[i] = pSrc[i]; + } + } +} + +inline uint32_t memcpy_ip(const uint8_t *pIpAddress) { +#ifdef __ARM_ARCH_7A__ + // Ensure destination pointer is aligned + if ((reinterpret_cast(pIpAddress) & ((sizeof(uint32_t) - 1))) == 0) { + // Destination pointer is already aligned, perform fast copy + return *reinterpret_cast(pIpAddress); + } else +#endif + { // Destination pointer is not aligned, copy byte by byte + typedef union pcast32 { + uint32_t u32; + uint8_t u8[4]; + } _pcast32; + + _pcast32 src; +#ifdef __ARM_ARCH_7A__ + volatile auto *pSrc = pIpAddress; + volatile auto *pDst = src.u8; +#else + auto *pSrc = pIpAddress; + auto *pDst = src.u8; +#endif + for (uint32_t i = 0; i < IPv4_ADDR_LEN; i++) { + pDst[i] = pSrc[i]; + } + + return src.u32; + } +} +} // namespace net + #endif /* NET_MEMCPY_H_ */ diff --git a/lib-network/src/net/net_packets.h b/lib-network/src/net/net_packets.h deleted file mode 100644 index d3b0f3e..0000000 --- a/lib-network/src/net/net_packets.h +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file net_packets.h - * - */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef NET_PACKETS_H_ -#define NET_PACKETS_H_ - -#include - -#if !defined (PACKED) -# define PACKED __attribute__((packed)) -#endif - -enum MTU { - MTU_SIZE = 1500 -}; - -enum ETHER_TYPE { - ETHER_TYPE_IPv4 = 0x0800, - ETHER_TYPE_ARP = 0x0806 -}; - -enum ETH_ADDR { - ETH_ADDR_LEN = 6 -}; - -enum IPv4_ADDR { - IPv4_ADDR_LEN = 4 -}; - -enum IPv4_PROTO { - IPv4_PROTO_ICMP = 1, - IPv4_PROTO_IGMP = 2, - IPv4_PROTO_TCP = 6, - IPv4_PROTO_UDP = 17 -}; - -enum IPv4_FLAG { - IPv4_FLAG_LF = 0x0000, - IPv4_FLAG_MF = 0x2000, - IPv4_FLAG_DF = 0x4000 -}; - -#define IPv4_BROADCAST 0xffffffff - -enum ARP_HARDWARE_TYPE { - ARP_HWTYPE_ETHERNET = 1 -}; - -enum ARP_PROTOCOL_TYPE { - ARP_PRTYPE_IPv4 = ETHER_TYPE_IPv4 -}; - -enum ARP_HARDWARE { - ARP_HARDWARE_SIZE = ETH_ADDR_LEN -}; - -enum ARP_PROTOCOL { - ARP_PROTOCOL_SIZE = IPv4_ADDR_LEN -}; - -enum ARP_OPCODE { - ARP_OPCODE_RQST = 1, - ARP_OPCODE_REPLY = 2 -}; - -enum IGMP_TYPE { - IGMP_TYPE_QUERY = 0x11, - IGMP_TYPE_REPORT = 0x16, - IGMP_TYPE_LEAVE = 0x17 -}; - -enum ICMP_TYPE { - ICMP_TYPE_ECHO_REPLY = 0, - ICMP_TYPE_ECHO = 8 -}; - -enum ICMP_CODE { - ICMP_CODE_ECHO = 0 -}; - -struct ether_header { - uint8_t dst[ETH_ADDR_LEN]; /* 6 */ - uint8_t src[ETH_ADDR_LEN]; /* 12 */ - uint16_t type; /* 14 */ -} PACKED; - -struct arp_packet { - uint16_t hardware_type; /* 2 */ - uint16_t protocol_type; /* 4 */ - uint8_t hardware_size; /* 5 */ - uint8_t protocol_size; /* 6 */ - uint16_t opcode; /* 8 */ - uint8_t sender_mac[ETH_ADDR_LEN];/*14 */ - uint8_t sender_ip[IPv4_ADDR_LEN];/* 18 */ - uint8_t target_mac[ETH_ADDR_LEN];/*24 */ - uint8_t target_ip[IPv4_ADDR_LEN];/* 28 */ - uint8_t padding[18]; /* 46 */ /* +14 = 60 */ -} PACKED; - -struct ip4_header { - uint8_t ver_ihl; /* 1 */ - uint8_t tos; /* 2 */ - uint16_t len; /* 4 */ - uint16_t id; /* 6 */ - uint16_t flags_froff; /* 8 */ - uint8_t ttl; /* 9 */ - uint8_t proto; /* 10 */ - uint16_t chksum; /* 12 */ - uint8_t src[IPv4_ADDR_LEN]; /* 16 */ - uint8_t dst[IPv4_ADDR_LEN]; /* 20 */ -} PACKED; - -struct t_igmp_packet { - uint8_t type; - uint8_t max_resp_time; - uint16_t checksum; - uint8_t group_address[IPv4_ADDR_LEN]; -} PACKED; - -struct t_icmp_packet { - uint8_t type; /* 1 */ - uint8_t code; /* 2 */ - uint16_t checksum; /* 4 */ - uint8_t parameter[4]; /* 8 */ -#define ICMP_HEADER_SIZE 8 -#define ICMP_PAYLOAD_SIZE (MTU_SIZE - ICMP_HEADER_SIZE - sizeof(struct ip4_header)) - uint8_t payload[ICMP_PAYLOAD_SIZE]; -} PACKED; - -struct t_udp_packet { - uint16_t source_port; /* 2 */ - uint16_t destination_port; /* 4 */ - uint16_t len; /* 6 */ - uint16_t checksum; /* 8 */ -#define UDP_HEADER_SIZE 8 -#define UDP_DATA_SIZE (MTU_SIZE - UDP_HEADER_SIZE - sizeof(struct ip4_header)) - uint8_t data[UDP_DATA_SIZE]; -}PACKED; - -struct t_tcp_packet { - uint16_t srcpt; /* 2 */ - uint16_t dstpt; /* 4 */ - uint32_t seqnum; /* 8 */ - uint32_t acknum; /* 12 */ - uint8_t offset; /* 13 */ - uint8_t control; /* 14 */ - uint16_t window; /* 16 */ - uint16_t checksum; /* 18 */ - uint16_t urgent; /* 20 */ -#define TCP_HEADER_SIZE 20 -#define TCP_DATA_SIZE (MTU_SIZE - TCP_HEADER_SIZE - sizeof(struct ip4_header) - 20U) - uint8_t data[TCP_DATA_SIZE]; -} PACKED; - -struct t_arp { - struct ether_header ether; - struct arp_packet arp; -} PACKED; - -struct t_ip4 { - struct ether_header ether; - struct ip4_header ip4; -} PACKED; - -struct t_igmp { - struct ether_header ether; - struct ip4_header ip4; - union { - struct { - uint32_t ip4_options; - struct t_igmp_packet igmp; - } report; - struct t_igmp_packet igmp; - } igmp; -} PACKED; - -struct t_icmp { - struct ether_header ether; - struct ip4_header ip4; - struct t_icmp_packet icmp; -} PACKED; - -struct t_udp { - struct ether_header ether; - struct ip4_header ip4; - struct t_udp_packet udp; -} PACKED; - -struct t_tcp { - struct ether_header ether; - struct ip4_header ip4; - struct t_tcp_packet tcp; -} PACKED; - -#define IPv4_UDP_HEADERS_SIZE (sizeof(struct ip4_header) + UDP_HEADER_SIZE) /* IP | UDP */ -#define UDP_PACKET_HEADERS_SIZE (sizeof(struct ether_header) + IPv4_UDP_HEADERS_SIZE) /* ETH | IP | UDP */ - -#define IPv4_IGMP_REPORT_HEADERS_SIZE (sizeof(struct t_igmp) - sizeof(struct ether_header)) -#define IGMP_REPORT_PACKET_SIZE (sizeof(struct t_igmp)) - -#define IPv4_ICMP_HEADERS_SIZE (sizeof(struct t_icmp) - sizeof(struct ether_header)) - -#endif /* NET_PACKETS_H_ */ diff --git a/lib-network/src/net/net_platform.h b/lib-network/src/net/net_platform.h index 79f9343..8f5ce44 100644 --- a/lib-network/src/net/net_platform.h +++ b/lib-network/src/net/net_platform.h @@ -31,7 +31,7 @@ * https://www.gd32-dmx.org/memory.html */ # include "gd32.h" -# if defined (GD32F207RG) || defined (GD32F4XX) +# if defined (GD32F207RG) || defined (GD32F4XX) || defined(GD32H7XX) # define SECTION_NETWORK __attribute__ ((section (".network"))) # else # define SECTION_NETWORK diff --git a/lib-network/src/net/net_private.h b/lib-network/src/net/net_private.h old mode 100755 new mode 100644 index 93c4da7..336c4c5 --- a/lib-network/src/net/net_private.h +++ b/lib-network/src/net/net_private.h @@ -2,7 +2,7 @@ * @file net_private.h * */ -/* Copyright (C) 2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2023-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,50 +28,47 @@ #include -#include "net_packets.h" #include "net_platform.h" -#include "net_debug.h" -#include "dhcp_internal.h" -#include "tftp_internal.h" -#include "ntp_internal.h" +#include "net/arp.h" +#include "net/protocol/icmp.h" +#include "net/protocol/igmp.h" +#include "net/protocol/udp.h" +#include "net/protocol/tcp.h" #ifndef ALIGNED # define ALIGNED __attribute__ ((aligned (4))) #endif -extern "C" { -int console_error(const char *); -void emac_eth_send(void *, int); +namespace net::arp { +enum class EthSend { + IS_NORMAL +#if defined CONFIG_ENET_ENABLE_PTP + , IS_TIMESTAMP +#endif +}; +} // namespace net::arp + +extern "C" void console_error(const char *); + +void emac_eth_send(void *, uint32_t); +#if defined CONFIG_ENET_ENABLE_PTP +void emac_eth_send_timestamp(void *, uint32_t); +#endif int emac_eth_recv(uint8_t **); -void emac_free_pkt(void); -} +void emac_free_pkt(); +namespace net { void net_handle(); uint16_t net_chksum(const void *, uint32_t); void net_timers_run(); -void arp_init(); -void arp_handle(struct t_arp *); -bool arp_do_probe(); -void arp_cache_init(); -void arp_send_request(uint32_t); -void arp_send_probe(); -void arp_send_announcement(); -void arp_cache_update(const uint8_t *, uint32_t); -uint32_t arp_cache_lookup(uint32_t, uint8_t *); - void ip_init(); void ip_set_ip(); void ip_shutdown(); void ip_handle(struct t_ip4 *); -int dhcp_client(const char *); -void dhcp_client_release(); - -bool rfc3927(); - void udp_init(); void udp_set_ip(); void udp_handle(struct t_udp *); @@ -81,7 +78,6 @@ void igmp_init(); void igmp_set_ip(); void igmp_handle(struct t_igmp *); void igmp_shutdown(); -void igmp_timer(); void icmp_handle(struct t_icmp *); void icmp_shutdown(); @@ -90,5 +86,6 @@ void tcp_init(); void tcp_run(); void tcp_handle(struct t_tcp *); void tcp_shutdown(); +} // namespace net #endif /* NET_PRIVATE_H_ */ diff --git a/lib-network/src/net/net_ptp.cpp b/lib-network/src/net/net_ptp.cpp new file mode 100755 index 0000000..8a4b695 --- /dev/null +++ b/lib-network/src/net/net_ptp.cpp @@ -0,0 +1,35 @@ +/** + * @file net_ptp.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@orangepi-dmx.nl + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +namespace net { +namespace globals { +uint32_t ptpTimestamp[2]; +} // namespace globals + +void __attribute__((weak)) ptp_handle([[maybe_unused]] const uint8_t *pBuffer, [[maybe_unused]] const uint32_t nLength) {} +void __attribute__((weak)) ptp_run() {} +} // namespace net diff --git a/lib-network/src/net/netif.cpp b/lib-network/src/net/netif.cpp new file mode 100755 index 0000000..975b1e6 --- /dev/null +++ b/lib-network/src/net/netif.cpp @@ -0,0 +1,306 @@ +/** + * @file netif.cpp + * + */ +/* Copyright (C) 2024 by Arjan van Vught mailto:info@gd32-dmx.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if defined (DEBUG_NET_NETIF) +# undef NDEBUG +#endif + +#include + +#include "netif.h" +#include "net/acd.h" +#include "net/autoip.h" +#include "net/dhcp.h" +#include "net/igmp.h" + +#include "debug.h" + +namespace net { +namespace globals { +struct netif netif_default; +extern uint32_t nBroadcastMask; +extern uint32_t nOnNetworkMask; +} // namespace globals + +extern void arp_init(); +extern void ip_set_ip(); + +static netif_ext_callback_fn callback_fn; + +static void default_callback([[maybe_unused]] const uint16_t reason, [[maybe_unused]] const netif_ext_callback_args_t* args) { + DEBUG_PRINTF("%u", reason); +} + +void netif_init() { + auto &netif = net::globals::netif_default; + + netif.ip.addr = 0; + netif.netmask.addr = 0; + netif.gw.addr = 0; + netif.broadcast_ip.addr = 0; + netif.secondary_ip.addr = 2 + + ((static_cast(netif.hwaddr[3])) << 8) + + ((static_cast(netif.hwaddr[4])) << 16) + + ((static_cast(netif.hwaddr[5])) << 24); + netif.flags = 0; + netif.dhcp = nullptr; + netif.acd = nullptr; + netif.autoip = nullptr; + + callback_fn = &default_callback; + + net::arp_init(); +} + +static void netif_do_update_globals() { + auto &netif = net::globals::netif_default; + netif.broadcast_ip.addr = (netif.ip.addr | ~netif.netmask.addr); + + globals::nBroadcastMask = ~(netif.netmask.addr); + globals::nOnNetworkMask =netif.ip.addr & netif.netmask.addr; + + ip_set_ip(); +} + +static void netif_do_ip_addr_changed([[maybe_unused]] const ip4_addr_t old_addr,[[maybe_unused]] const ip4_addr_t new_addr) { +// tcp_netif_ip_addr_changed(old_addr, new_addr); +// udp_netif_ip_addr_changed(old_addr, new_addr); + ip_set_ip(); +} + +static void netif_issue_reports() { + const auto &netif = net::globals::netif_default; + + if (!(netif.flags & netif::NETIF_FLAG_LINK_UP)) { + return; + } + + if (netif.ip.addr != 0) { + igmp_report_groups(); + } +} + +static bool netif_do_set_ipaddr(const ip4_addr_t ipaddr, ip4_addr_t &old_addr) { + DEBUG_ENTRY + auto &netif = net::globals::netif_default; + + DEBUG_PRINTF(IPSTR " " IPSTR, IP2STR(ipaddr.addr), IP2STR(netif.ip.addr)); + + // Update the address if it's different + if (ipaddr.addr != netif.ip.addr) { + old_addr.addr = netif.ip.addr; + + netif_do_ip_addr_changed(old_addr, ipaddr); + acd_netif_ip_addr_changed(old_addr, ipaddr); + + netif.ip.addr = ipaddr.addr; + + netif_do_update_globals(); + netif_issue_reports(); + + DEBUG_EXIT + return true; // address changed + } + + DEBUG_EXIT + return false; // address unchanged +} + +static bool netif_do_set_netmask(const ip4_addr_t netmask, ip4_addr_t &old_nm) { + DEBUG_ENTRY + auto &netif = net::globals::netif_default; + + if (netmask.addr != netif.netmask.addr) { + old_nm.addr = netif.netmask.addr; + netif.netmask.addr = netmask.addr; + + netif_do_update_globals(); + + DEBUG_EXIT + return true; // netmask changed + } + + DEBUG_EXIT + return false; // netmask unchanged +} + +static bool netif_do_set_gw(const ip4_addr_t gw, ip4_addr_t &old_gw) { + DEBUG_ENTRY + auto &netif = net::globals::netif_default; + + if (gw.addr != netif.gw.addr) { + old_gw.addr = netif.gw.addr; + netif.gw.addr = gw.addr; + + DEBUG_EXIT + return true; // gateway changed + } + + DEBUG_EXIT + return false; // gateway unchanged +} + +void netif_set_ipaddr(const ip4_addr_t ipaddr) { + ip4_addr_t old_addr; + + if (netif_do_set_ipaddr(ipaddr, old_addr)) { + netif_ext_callback_args_t args; + args.ipv4_changed.old_address.addr = old_addr.addr; + callback_fn(NetifReason::NSC_IPV4_ADDRESS_CHANGED, &args); + } +} + +void netif_set_netmask(const ip4_addr_t netmask) { + ip4_addr_t old_nm; + + if (netif_do_set_netmask(netmask, old_nm)) { + netif_ext_callback_args_t args; + args.ipv4_changed.old_netmask = old_nm; + callback_fn(NetifReason::NSC_IPV4_NETMASK_CHANGED, &args); + } +} + +void netif_set_gw(const ip4_addr_t gw) { + ip4_addr_t old_gw; + + if (netif_do_set_gw(gw, old_gw)) { + netif_ext_callback_args_t args; + args.ipv4_changed.old_gw = old_gw; + callback_fn(NetifReason::NSC_IPV4_GATEWAY_CHANGED, &args); + } +} + +void netif_set_addr(const ip4_addr_t ipaddr, const ip4_addr_t netmask, const ip4_addr_t gw) { + DEBUG_ENTRY + DEBUG_PRINTF(IPSTR " " IPSTR " " IPSTR, IP2STR(ipaddr.addr), IP2STR(netmask.addr), IP2STR(gw.addr)); + + auto change_reason = NetifReason::NSC_NONE; + netif_ext_callback_args_t cb_args; + + ip4_addr_t old_addr; + ip4_addr_t old_nm; + ip4_addr_t old_gw; + + const auto remove = (ipaddr.addr == 0); + + if (remove) { + /* when removing an address, we have to remove it *before* changing netmask/gw + to ensure that tcp RST segment can be sent correctly */ + if (netif_do_set_ipaddr(ipaddr, old_addr)) { + change_reason |= NetifReason::NSC_IPV4_ADDRESS_CHANGED; + cb_args.ipv4_changed.old_address.addr = old_addr.addr; + } + } + + if (netif_do_set_netmask(netmask, old_nm)) { + change_reason |= NetifReason::NSC_IPV4_NETMASK_CHANGED; + cb_args.ipv4_changed.old_netmask.addr = old_nm.addr; + } + + if (netif_do_set_gw(gw, old_gw)) { + change_reason |= NetifReason::NSC_IPV4_GATEWAY_CHANGED; + cb_args.ipv4_changed.old_gw = old_gw; + } + + if (!remove) { + /* set ipaddr last to ensure netmask/gw have been set when status callback is called */ + if (netif_do_set_ipaddr(ipaddr, old_addr)) { + change_reason |= NetifReason::NSC_IPV4_ADDRESS_CHANGED; + cb_args.ipv4_changed.old_address.addr = old_addr.addr; + } + } + + if (change_reason != NetifReason::NSC_NONE) { + change_reason |= NetifReason::NSC_IPV4_SETTINGS_CHANGED; + } + + if (!remove) { + /* Issue a callback even if the address hasn't changed, eg. DHCP reboot */ + change_reason |= NetifReason::NSC_IPV4_ADDR_VALID; + } + + DEBUG_PRINTF("change_reason=%u", change_reason); + + if (change_reason != NetifReason::NSC_NONE) { + callback_fn(change_reason, &cb_args); + } + + DEBUG_EXIT +} + +void netif_add_ext_callback(netif_ext_callback_fn fn) { + callback_fn = fn; +} + +/* + * Link + */ + +void netif_set_link_up() { + DEBUG_ENTRY + const auto &netif = net::globals::netif_default; + + if (!(netif.flags & netif::NETIF_FLAG_LINK_UP)) { + netif_set_flags(netif::NETIF_FLAG_LINK_UP); + + dhcp_network_changed_link_up(); + + autoip_network_changed_link_up(); + + netif_issue_reports(); + + netif_ext_callback_args_t args; + args.link_changed.state = 1; + callback_fn(NetifReason::NSC_LINK_CHANGED, &args); + + DEBUG_EXIT + return; + } + + DEBUG_EXIT +} + +void netif_set_link_down() { + DEBUG_ENTRY + const auto &netif = net::globals::netif_default; + + if (netif.flags & netif::NETIF_FLAG_LINK_UP) { + netif_clear_flags(netif::NETIF_FLAG_LINK_UP); + + autoip_network_changed_link_down(); + + acd_network_changed_link_down(); + + netif_ext_callback_args_t args; + args.link_changed.state = 0; + callback_fn(NetifReason::NSC_LINK_CHANGED, &args); + + DEBUG_EXIT + return; + } + + DEBUG_EXIT +} +} // namespace net diff --git a/lib-network/src/net/rfc3927.cpp b/lib-network/src/net/rfc3927.cpp deleted file mode 100644 index ba7b9c4..0000000 --- a/lib-network/src/net/rfc3927.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file rfc3927.cpp - * - */ -/* Copyright (C) 2020-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "net.h" -#include "net_private.h" - -#include "hardware.h" - -#include "../../config/net_config.h" - -/* - * https://www.rfc-editor.org/rfc/rfc3927.html - * Dynamic Configuration of IPv4 Link-Local Addresses - */ - -static const uint32_t s_ip_begin = 0x0100FEA9; // 169.254.0.1 -static const uint32_t s_ip_end = 0xFFFEFEA9; // 169.254.254.255 - -namespace net { -namespace globals { -extern struct IpInfo ipInfo; -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net - -bool rfc3927() { - DEBUG_ENTRY - - const auto mask = net::globals::macAddress[3] + (net::globals::macAddress[4] << 8); - auto ip = s_ip_begin | static_cast(mask << 16); - - DEBUG_PRINTF("ip=" IPSTR, IP2STR(ip)); - - auto nCount = 0; - const auto nMillis = Hardware::Get()->Millis(); - - do { - DEBUG_PRINTF(IPSTR, IP2STR(ip)); - - net::globals::ipInfo.ip.addr = ip; - - if (!arp_do_probe()) { - net::globals::ipInfo.gw.addr = ip; - net::globals::ipInfo.netmask.addr = 0x0000FFFF; - - DEBUG_EXIT - return true; - } - - ip = __builtin_bswap32(__builtin_bswap32(ip) + 1); - - if (ip == s_ip_end) { - ip = s_ip_begin; - } - - nCount++; - } while ((nCount < 0xFF) && ((Hardware::Get()->Millis() - nMillis) < 500)); - - net::globals::ipInfo.ip.addr = 0; - net::globals::ipInfo.gw.addr = 0; - net::globals::ipInfo.netmask.addr = 0; - - DEBUG_EXIT - return false; -} diff --git a/lib-network/src/net/tcp.cpp b/lib-network/src/net/tcp.cpp index 4dda207..c219828 100644 --- a/lib-network/src/net/tcp.cpp +++ b/lib-network/src/net/tcp.cpp @@ -2,7 +2,7 @@ * @file tcp.cpp * */ -/* Copyright (C) 2021-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,39 +29,43 @@ * LISTEN -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED:LISTEN */ +#if defined (DEBUG_NET_TCP) +# undef NDEBUG +#endif + +#pragma GCC diagnostic push #if (__GNUC__ < 10) -# pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wconversion" # pragma GCC diagnostic ignored "-Wsign-conversion" #endif +#pragma GCC push_options +#pragma GCC optimize ("O2") +#pragma GCC optimize ("no-tree-loop-distribute-patterns") #include #include #include #include +#include "../config/net_config.h" + #include "net.h" +#include "net/protocol/tcp.h" + +#include "net_memcpy.h" #include "net_private.h" #include "hardware.h" -#include "../config/net_config.h" +#include "debug.h" +namespace net { #define TCP_RX_MSS (TCP_DATA_SIZE) #define TCP_RX_MAX_ENTRIES (1U << 1) // Must always be a power of 2 #define TCP_RX_MAX_ENTRIES_MASK (TCP_RX_MAX_ENTRIES - 1) #define TCP_MAX_RX_WND (TCP_RX_MAX_ENTRIES * TCP_RX_MSS); - #define TCP_TX_MSS (TCP_DATA_SIZE) -#define MAX_TCBS_ALLOWED 6 - -namespace net { -namespace globals { -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net - /** * Transmission control block (TCB) */ @@ -128,7 +132,7 @@ struct ReceiveQueue { }; struct Port { - tcb TCB[MAX_TCBS_ALLOWED]; + tcb TCB[TCP_MAX_TCBS_ALLOWED]; ReceiveQueue receiveQueue; uint16_t nLocalPort; }; @@ -253,13 +257,13 @@ static constexpr bool SEQ_GT(const uint32_t x, const uint32_t y) { return static_cast(x - y) > 0; } -static constexpr bool SEQ_GEQ(const uint32_t x, const uint32_t y) { - return static_cast(x - y) >= 0; -} - -static constexpr bool SEQ_BETWEEN(const uint32_t l, const uint32_t x, const uint32_t h) { - return SEQ_LT(l, x) && SEQ_LT(x, h); -} +//static constexpr bool SEQ_GEQ(const uint32_t x, const uint32_t y) { +// return static_cast(x - y) >= 0; +//} +// +//static constexpr bool SEQ_BETWEEN(const uint32_t l, const uint32_t x, const uint32_t h) { +// return SEQ_LT(l, x) && SEQ_LT(x, h); +//} static constexpr bool SEQ_BETWEEN_L(const uint32_t l, const uint32_t x, const uint32_t h) { return SEQ_LEQ(l, x) && SEQ_LT(x, h); // low border inclusive @@ -322,7 +326,7 @@ __attribute__((cold)) void tcp_init() { DEBUG_ENTRY /* Ethernet */ - memcpy(s_tcp.ether.src, net::globals::macAddress, ETH_ADDR_LEN); + std::memcpy(s_tcp.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); s_tcp.ether.type = __builtin_bswap16(ETHER_TYPE_IPv4); /* IPv4 */ s_tcp.ip4.ver_ihl = 0x45; @@ -360,8 +364,8 @@ static uint16_t _chksum(struct t_tcp *pTcp, const struct tcb *pTcb, uint16_t nLe memcpy(buf, pseu, TCP_PSEUDO_LEN); // Generate TCP psuedo header - memcpy(pseu->srcIp, pTcb->localIp, IPv4_ADDR_LEN); - memcpy(pseu->dstIp, pTcb->remoteIp, IPv4_ADDR_LEN); + std::memcpy(pseu->srcIp, pTcb->localIp, IPv4_ADDR_LEN); + std::memcpy(pseu->dstIp, pTcb->remoteIp, IPv4_ADDR_LEN); pseu->zero = 0; pseu->proto = IPv4_PROTO_TCP; pseu->length = __builtin_bswap16(nLength); @@ -391,12 +395,12 @@ static void send_package(const struct tcb *pTcb, const struct SendInfo &sendInfo const auto tcplen = nHeaderLength + pTcb->TX.size; /* Ethernet */ - memcpy(s_tcp.ether.dst, pTcb->remoteEthAddr, ETH_ADDR_LEN); + std::memcpy(s_tcp.ether.dst, pTcb->remoteEthAddr, ETH_ADDR_LEN); /* IPv4 */ s_tcp.ip4.id = s_id++; s_tcp.ip4.len = __builtin_bswap16(static_cast(tcplen + sizeof(struct ip4_header))); - memcpy(s_tcp.ip4.src, pTcb->localIp, IPv4_ADDR_LEN); - memcpy(s_tcp.ip4.dst, pTcb->remoteIp, IPv4_ADDR_LEN); + std::memcpy(s_tcp.ip4.src, pTcb->localIp, IPv4_ADDR_LEN); + std::memcpy(s_tcp.ip4.dst, pTcb->remoteIp, IPv4_ADDR_LEN); s_tcp.ip4.chksum = 0; #if !defined (CHECKSUM_BY_HARDWARE) s_tcp.ip4.chksum = net_chksum(reinterpret_cast(&s_tcp.ip4), 20); @@ -545,26 +549,79 @@ static void scan_options(struct t_tcp *pTcp, struct tcb *pTcb, const int32_t nDa } __attribute__((hot)) void tcp_run() { - for (auto nIndexPort = 0; nIndexPort < TCP_MAX_PORTS_ALLOWED; nIndexPort++) { - for (auto nIndexTCB = 0; nIndexTCB < MAX_TCBS_ALLOWED; nIndexTCB++) { - auto *pTCB = &s_Port[nIndexPort].TCB[nIndexTCB]; - - if (pTCB->state == STATE_CLOSE_WAIT) { - struct SendInfo info; - info.SEQ = pTCB->SND.NXT; - info.ACK = pTCB->RCV.NXT; + for (auto& port : s_Port) { + for (auto& tcb : port.TCB) { + if (tcb.state == STATE_CLOSE_WAIT) { + SendInfo info; + info.SEQ = tcb.SND.NXT; + info.ACK = tcb.RCV.NXT; info.CTL = Control::FIN | Control::ACK; - send_package(pTCB, info); + send_package(&tcb, info); - NEW_STATE(pTCB, STATE_LAST_ACK); + NEW_STATE(&tcb, STATE_LAST_ACK); - pTCB->SND.NXT++; + tcb.SND.NXT++; } } } } +static bool find_matching_tcb(const t_tcp *pTcp, const uint32_t nIndexPort, uint32_t& nIndexTCB) { + for (nIndexTCB = 0; nIndexTCB < TCP_MAX_TCBS_ALLOWED; nIndexTCB++) { + auto *pTCB = &s_Port[nIndexPort].TCB[nIndexTCB]; + + if (pTCB->state == STATE_LISTEN) { + continue; + } + + if (pTCB->nRemotePort == pTcp->tcp.srcpt && memcmp(pTCB->remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN) == 0) { + return true; + } + } + + return false; +} + +static bool find_available_tcb(const uint32_t nIndexPort, uint32_t& nIndexTCB) { + for (nIndexTCB = 0; nIndexTCB < TCP_MAX_TCBS_ALLOWED; nIndexTCB++) { + auto *pTCB = &s_Port[nIndexPort].TCB[nIndexTCB]; + + if (pTCB->state == STATE_LISTEN) { + DEBUG_PUTS("pTCB->state == STATE_LISTEN"); + return true; + } + } + + return false; +} + +static void find_tcb(const t_tcp *pTcp, uint32_t& nIndexPort, uint32_t& nIndexTCB) { + // Search each port for a match with the destination port + for (nIndexPort = 0; nIndexPort < TCP_MAX_PORTS_ALLOWED; nIndexPort++) { + if (s_Port[nIndexPort].nLocalPort != pTcp->tcp.dstpt) { + continue; + } + + // Search for an existing active TCB matching the source IP and port + if (find_matching_tcb(pTcp, nIndexPort, nIndexTCB)) { + DEBUG_EXIT + return; + } + + // If no matching TCB, find an available TCB in listening state + if (find_available_tcb(nIndexPort, nIndexTCB)) { + DEBUG_EXIT + return; + } + + // If no available TCB, trigger retransmission + DEBUG_PUTS("MAX_TCB_ALLOWED -> Force retransmission"); + DEBUG_EXIT + return; + } +} + /** * https://www.rfc-editor.org/rfc/rfc9293.html#name-segment-arrives */ @@ -576,69 +633,33 @@ __attribute__((hot)) void tcp_handle(struct t_tcp *pTcp) { DEBUG_PRINTF(IPSTR ":%d[%d] -> %d", pTcp->ip4.src[0], pTcp->ip4.src[1], pTcp->ip4.src[2], pTcp->ip4.src[3], pTcp->tcp.dstpt, pTcp->tcp.srcpt, tcplen); - uint32_t nIndexPort; - /* - src/net/tcp.cpp: In function 'void tcp_handle(t_tcp*)': -src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this function [-Werror=maybe-uninitialized] - 871 | switch (pTCB->state) { - */ + uint32_t nIndexPort = 0; uint32_t nIndexTCB = 0; - - // Find a TCB - for (nIndexPort = 0; nIndexPort < TCP_MAX_PORTS_ALLOWED; nIndexPort++) { - if (s_Port[nIndexPort].nLocalPort == pTcp->tcp.dstpt) { - // Find an active TCB - for (nIndexTCB = 0; nIndexTCB < MAX_TCBS_ALLOWED; nIndexTCB++) { - auto *pTCB = &s_Port[nIndexPort].TCB[nIndexTCB]; - if (pTCB->state != STATE_LISTEN) { - if ((pTCB->nRemotePort == pTcp->tcp.srcpt) && (memcmp(pTCB->remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN) == 0)) { - break; - } - } - } - - if (nIndexTCB == MAX_TCBS_ALLOWED) { - // Find an available TCB - for (nIndexTCB = 0; nIndexTCB < MAX_TCBS_ALLOWED; nIndexTCB++) { - auto *pTCB = &s_Port[nIndexPort].TCB[nIndexTCB]; - if (pTCB->state == STATE_LISTEN) { - break; - } - } - - if (nIndexTCB == MAX_TCBS_ALLOWED) { - DEBUG_PUTS("MAX_TCB_ALLOWED -> Force retransmission"); - DEBUG_EXIT - return; - } - } - - break; - } - } + find_tcb(pTcp, nIndexPort, nIndexTCB); + DEBUG_PRINTF("nIndexPort=%u, nIndexTCB=%u", nIndexPort, nIndexTCB); const auto nDataOffset = offset2octets(pTcp->tcp.offset); // https://www.rfc-editor.org/rfc/rfc9293.html#name-closed-state // CLOSED (i.e., TCB does not exist) if (nIndexPort == TCP_MAX_PORTS_ALLOWED) { - DEBUG_PUTS("TCP_MAX_PORTS_ALLOWED"); struct tcb TCB; - memset(&TCB, 0, sizeof(struct tcb)); + std::memset(&TCB, 0, sizeof(struct tcb)); TCB.nLocalPort = pTcp->tcp.dstpt; - memcpy(TCB.localIp, pTcp->ip4.dst, IPv4_ADDR_LEN); + std::memcpy(TCB.localIp, pTcp->ip4.dst, IPv4_ADDR_LEN); TCB.nRemotePort = pTcp->tcp.srcpt; - memcpy(TCB.remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN); - memcpy(TCB.remoteEthAddr, pTcp->ether.src, ETH_ADDR_LEN); + std::memcpy(TCB.remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN); + std::memcpy(TCB.remoteEthAddr, pTcp->ether.src, ETH_ADDR_LEN); _bswap32(pTcp); scan_options(pTcp, &TCB, nDataOffset); send_reset(pTcp, &TCB); + DEBUG_PUTS("TCP_MAX_PORTS_ALLOWED"); DEBUG_EXIT return; } @@ -649,19 +670,6 @@ src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this fun pTcp->tcp.window = __builtin_bswap16(pTcp->tcp.window); pTcp->tcp.urgent = __builtin_bswap16(pTcp->tcp.urgent); - DEBUG_PRINTF("%c%c%c%c%c%c SEQ=%u, ACK=%u, tcplen=%u, data_offset=%u, data_length=%u", - pTcp->tcp.control & Control::URG ? 'U' : '-', - pTcp->tcp.control & Control::ACK ? 'A' : '-', - pTcp->tcp.control & Control::PSH ? 'P' : '-', - pTcp->tcp.control & Control::RST ? 'R' : '-', - pTcp->tcp.control & Control::SYN ? 'S' : '-', - pTcp->tcp.control & Control::FIN ? 'F' : '-', - _get_seqnum(pTcp), - _get_acknum(pTcp), - tcplen, - nDataOffset, - nDataLength); - SendInfo sendInfo; const auto SEG_LEN = nDataLength; @@ -691,11 +699,11 @@ src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this fun // https://www.rfc-editor.org/rfc/rfc9293.html#name-listen-state if (pTCB->state == STATE_LISTEN) { - memcpy(pTCB->localIp, pTcp->ip4.dst, IPv4_ADDR_LEN); + std::memcpy(pTCB->localIp, pTcp->ip4.dst, IPv4_ADDR_LEN); pTCB->nRemotePort = pTcp->tcp.srcpt; - memcpy(pTCB->remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN); - memcpy(pTCB->remoteEthAddr, pTcp->ether.src, ETH_ADDR_LEN); + std::memcpy(pTCB->remoteIp, pTcp->ip4.src, IPv4_ADDR_LEN); + std::memcpy(pTCB->remoteEthAddr, pTcp->ether.src, ETH_ADDR_LEN); // First, check for a RST // An incoming RST should be ignored. @@ -711,6 +719,7 @@ src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this fun if (pTcp->tcp.control & Control::ACK) { send_reset(pTcp, pTCB); + DEBUG_PUTS("pTcp->tcp.control & Control::ACK"); DEBUG_EXIT return; } @@ -848,8 +857,9 @@ src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this fun return; } - DEBUG_PUTS("_send_reset"); send_reset(pTcp, pTCB); + + DEBUG_PUTS("pTcp->tcp.control & Control::SYN"); } /* fifth check the ACK field, *//* Page 72 */ @@ -874,8 +884,9 @@ src/net/tcp.cpp:871:31: error: 'nIndexTCB' may be used uninitialized in this fun return; } else { // - DEBUG_PUTS("_send_reset"); send_reset(pTcp, pTCB); + + DEBUG_PUTS(""); } break; case STATE_ESTABLISHED: @@ -1083,7 +1094,7 @@ int tcp_begin(const uint16_t nLocalPort) { if (s_Port[i].nLocalPort == 0) { s_Port[i].nLocalPort = nLocalPort; - for (uint32_t nIndexTCB = 0; nIndexTCB < MAX_TCBS_ALLOWED; nIndexTCB++) { + for (uint32_t nIndexTCB = 0; nIndexTCB < TCP_MAX_TCBS_ALLOWED; nIndexTCB++) { // create transmission control block's (TCB) _init_tcb(&s_Port[i].TCB[nIndexTCB], nLocalPort); } @@ -1125,15 +1136,17 @@ uint16_t tcp_read(const int32_t nHandleListen, const uint8_t **pData, uint32_t & return pQueueEntry->nSize; } -void tcp_write(const int32_t nHandleListen, const uint8_t *pBuffer, uint16_t nLength, uint32_t nHandleConnection) { - assert(nHandleListen >= 0); - assert(nHandleListen < TCP_MAX_PORTS_ALLOWED); - assert(pBuffer != nullptr); - assert(nHandleConnection < MAX_TCBS_ALLOWED); +static void _write(struct tcb *pTCB, const uint8_t *pBuffer, const uint32_t nLength, const bool isLastSegment) { + assert(nLength != 0); + assert(nLength <= static_cast(TCP_DATA_SIZE)); - nLength = std::min(nLength, static_cast(TCP_DATA_SIZE)); + DEBUG_PRINTF("nLength=%u, pTCB->SND.WND=%u", nLength, pTCB->SND.WND); - auto *pTCB = &s_Port[nHandleListen].TCB[nHandleConnection]; + if (nLength > pTCB->SND.WND) { + console_error("Retry or queue the data for later transmission\n"); + // TODO retry or queue the data for later transmission. + return; + } pTCB->TX.data = const_cast(pBuffer); pTCB->TX.size = nLength; @@ -1141,14 +1154,38 @@ void tcp_write(const int32_t nHandleListen, const uint8_t *pBuffer, uint16_t nLe struct SendInfo info; info.SEQ = pTCB->SND.NXT; info.ACK = pTCB->RCV.NXT; - info.CTL = Control::ACK | Control::PSH; + info.CTL = Control::ACK; + if (isLastSegment) { + info.CTL |= Control::PSH; + } send_package(pTCB, info); pTCB->TX.data = nullptr; pTCB->TX.size = 0; - pTCB->SND.NXT += nLength; + pTCB->SND.NXT += nLength; + pTCB->SND.WND -= nLength; } +void tcp_write(const int32_t nHandleListen, const uint8_t *pBuffer, uint32_t nLength, uint32_t nHandleConnection) { + assert(nHandleListen >= 0); + assert(nHandleListen < TCP_MAX_PORTS_ALLOWED); + assert(pBuffer != nullptr); + assert(nHandleConnection < TCP_MAX_TCBS_ALLOWED); + + auto *pTCB = &s_Port[nHandleListen].TCB[nHandleConnection]; + assert(pTCB != nullptr); + + const auto *p = pBuffer; + + while (nLength > 0) { + const auto nWriteLength = (nLength > TCP_DATA_SIZE) ? TCP_DATA_SIZE : nLength; + const bool isLastSegment = (nLength < TCP_DATA_SIZE); + _write(pTCB, p, nWriteLength, isLastSegment); + p += nWriteLength; + nLength -= nWriteLength; + } +} +} // namespace net // <--- diff --git a/lib-network/src/net/udp.cpp b/lib-network/src/net/udp.cpp index 5def0c6..f34f768 100644 --- a/lib-network/src/net/udp.cpp +++ b/lib-network/src/net/udp.cpp @@ -2,7 +2,7 @@ * @file udp.cpp * */ -/* Copyright (C) 2018-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2018-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,50 +23,51 @@ * THE SOFTWARE. */ +#if defined (DEBUG_NET_UDP) +# undef NDEBUG +#endif + +#if !defined (CONFIG_REMOTECONFIG_MINIMUM) +# pragma GCC push_options +# pragma GCC optimize ("O2") +# pragma GCC optimize ("no-tree-loop-distribute-patterns") +#endif + #include #include -#include #include #include +#include "../../config/net_config.h" + +#include "net/protocol/udp.h" + #include "net.h" #include "net_private.h" #include "net_memcpy.h" -#include "../../config/net_config.h" +#include "debug.h" + +namespace net { +namespace globals { +extern uint32_t nBroadcastMask; +} // namespace globals struct data_entry { uint32_t from_ip; + uint32_t size; uint16_t from_port; - uint16_t size; uint8_t data[UDP_DATA_SIZE]; } ALIGNED; -typedef union pcast32 { - uint32_t u32; - uint8_t u8[4]; -} _pcast32; - static uint16_t s_Port[UDP_MAX_PORTS_ALLOWED] SECTION_NETWORK ALIGNED; static struct data_entry s_data[UDP_MAX_PORTS_ALLOWED] SECTION_NETWORK ALIGNED; static struct t_udp s_send_packet SECTION_NETWORK ALIGNED; static uint16_t s_id SECTION_NETWORK ALIGNED; static uint8_t s_multicast_mac[ETH_ADDR_LEN] SECTION_NETWORK ALIGNED; -namespace net { -namespace globals { -extern struct IpInfo ipInfo; -extern uint32_t nBroadcastMask; -extern uint32_t nOnNetworkMask; -extern uint8_t macAddress[ETH_ADDR_LEN]; -} // namespace globals -} // namespace net - void udp_set_ip() { - _pcast32 src; - - src.u32 = net::globals::ipInfo.ip.addr; - memcpy(s_send_packet.ip4.src, src.u8, IPv4_ADDR_LEN); + net::memcpy_ip(s_send_packet.ip4.src, net::globals::netif_default.ip.addr); } void __attribute__((cold)) udp_init() { @@ -75,7 +76,7 @@ void __attribute__((cold)) udp_init() { s_multicast_mac[1] = 0x00; s_multicast_mac[2] = 0x5E; // Ethernet - memcpy(s_send_packet.ether.src, net::globals::macAddress, ETH_ADDR_LEN); + std::memcpy(s_send_packet.ether.src, net::globals::netif_default.hwaddr, ETH_ADDR_LEN); s_send_packet.ether.type = __builtin_bswap16(ETHER_TYPE_IPv4); // IPv4 s_send_packet.ip4.ver_ihl = 0x45; @@ -107,21 +108,86 @@ __attribute__((hot)) void udp_handle(struct t_udp *pUdp) { const auto nDataLength = static_cast(__builtin_bswap16(pUdp->udp.len) - UDP_HEADER_SIZE); const auto i = std::min(static_cast(UDP_DATA_SIZE), nDataLength); - net_memcpy(p_queue_entry->data, pUdp->udp.data, i); + net::memcpy(p_queue_entry->data, pUdp->udp.data, i); - _pcast32 src; - - memcpy(src.u8, pUdp->ip4.src, IPv4_ADDR_LEN); - p_queue_entry->from_ip = src.u32; + p_queue_entry->from_ip = net::memcpy_ip(pUdp->ip4.src); p_queue_entry->from_port = __builtin_bswap16(pUdp->udp.source_port); p_queue_entry->size = static_cast(i); return; + } + } + DEBUG_PRINTF(IPSTR ":%d[%x] " MACSTR, pUdp->ip4.src[0],pUdp->ip4.src[1],pUdp->ip4.src[2],pUdp->ip4.src[3], nDestinationPort, nDestinationPort, MAC2STR(pUdp->ether.dst)); +} + +template +static void udp_send_implementation(int nIndex, const uint8_t *pData, uint32_t nSize, uint32_t nRemoteIp, uint16_t nRemotePort) { + assert(nIndex >= 0); + assert(nIndex < UDP_MAX_PORTS_ALLOWED); + assert(s_Port[nIndex] != 0); + + //IPv4 + s_send_packet.ip4.id = s_id++; + s_send_packet.ip4.len = __builtin_bswap16(static_cast(nSize + IPv4_UDP_HEADERS_SIZE)); + s_send_packet.ip4.chksum = 0; + + //UDP + s_send_packet.udp.source_port = __builtin_bswap16( s_Port[nIndex]); + s_send_packet.udp.destination_port = __builtin_bswap16(nRemotePort); + s_send_packet.udp.len = __builtin_bswap16(static_cast(nSize + UDP_HEADER_SIZE)); + + nSize = std::min(static_cast(UDP_DATA_SIZE), nSize); + + net::memcpy(s_send_packet.udp.data, pData, nSize); + + if (nRemoteIp == network::IP4_BROADCAST) { + memset(s_send_packet.ether.dst, 0xFF, ETH_ADDR_LEN); + memset(s_send_packet.ip4.dst, 0xFF, IPv4_ADDR_LEN); + } else if ((nRemoteIp & net::globals::nBroadcastMask) == net::globals::nBroadcastMask) { + memset(s_send_packet.ether.dst, 0xFF, ETH_ADDR_LEN); + net::memcpy_ip(s_send_packet.ip4.dst, nRemoteIp); + } else { + if ((nRemoteIp & 0xF0) == 0xE0) { // Multicast, we know the MAC Address + typedef union pcast32 { + uint32_t u32; + uint8_t u8[4]; + } _pcast32; + _pcast32 multicast_ip; + + multicast_ip.u32 = nRemoteIp; + s_multicast_mac[3] = multicast_ip.u8[1] & 0x7F; + s_multicast_mac[4] = multicast_ip.u8[2]; + s_multicast_mac[5] = multicast_ip.u8[3]; + + std::memcpy(s_send_packet.ether.dst, s_multicast_mac, ETH_ADDR_LEN); + net::memcpy_ip(s_send_packet.ip4.dst, nRemoteIp); + } else { + if (S == net::arp::EthSend::IS_NORMAL) { + net::arp_send(&s_send_packet, nSize + UDP_PACKET_HEADERS_SIZE, nRemoteIp); + } +#if defined CONFIG_ENET_ENABLE_PTP + else if (S == net::arp::EthSend::IS_TIMESTAMP) { + net::arp_send_timestamp(&s_send_packet, nSize + UDP_PACKET_HEADERS_SIZE, nRemoteIp); + } +#endif + return; } } - DEBUG_PRINTF(IPSTR ":%d[%x]", pUdp->ip4.src[0],pUdp->ip4.src[1],pUdp->ip4.src[2],pUdp->ip4.src[3], nDestinationPort, nDestinationPort); +#if !defined (CHECKSUM_BY_HARDWARE) + s_send_packet.ip4.chksum = net_chksum(reinterpret_cast(&s_send_packet.ip4), sizeof(s_send_packet.ip4)); +#endif + + if (S == net::arp::EthSend::IS_NORMAL) { + emac_eth_send(reinterpret_cast(&s_send_packet), nSize + UDP_PACKET_HEADERS_SIZE); + } +#if defined CONFIG_ENET_ENABLE_PTP + else if (S == net::arp::EthSend::IS_TIMESTAMP) { + emac_eth_send_timestamp(reinterpret_cast(&s_send_packet), nSize); + } +#endif + return; } // --> @@ -163,7 +229,7 @@ int udp_end(uint16_t nLocalPort) { return -1; } -uint16_t udp_recv1(int nIndex, uint8_t *pData, uint16_t nSize, uint32_t *pFromIp, uint16_t *FromPort) { +uint32_t udp_recv1(int nIndex, uint8_t *pData, uint32_t nSize, uint32_t *pFromIp, uint16_t *FromPort) { assert(nIndex >= 0); assert(nIndex < UDP_MAX_PORTS_ALLOWED); @@ -174,7 +240,7 @@ uint16_t udp_recv1(int nIndex, uint8_t *pData, uint16_t nSize, uint32_t *pFromIp auto *p_data = &s_data[nIndex]; const auto i = std::min(nSize, p_data->size); - net_memcpy(pData, p_data->data, i); + net::memcpy(pData, p_data->data, i); *pFromIp = p_data->from_ip; *FromPort = p_data->from_port; @@ -184,104 +250,35 @@ uint16_t udp_recv1(int nIndex, uint8_t *pData, uint16_t nSize, uint32_t *pFromIp return i; } -uint16_t udp_recv2(int nIndex, const uint8_t **pData, uint32_t *pFromIp, uint16_t *pFromPort) { +uint32_t udp_recv2(int nIndex, const uint8_t **pData, uint32_t *pFromIp, uint16_t *pFromPort) { assert(nIndex >= 0); assert(nIndex < UDP_MAX_PORTS_ALLOWED); - if (__builtin_expect((s_data[nIndex].size == 0), 1)) { + auto &p_data = s_data[nIndex]; + + if (__builtin_expect((p_data.size == 0), 1)) { return 0; } - auto *p_data = &s_data[nIndex]; - - *pData = p_data->data; - *pFromIp = p_data->from_ip; - *pFromPort = p_data->from_port; + *pData = p_data.data; + *pFromIp = p_data.from_ip; + *pFromPort = p_data.from_port; - const auto nSize = p_data->size; + const auto nSize = p_data.size; - p_data->size = 0; + p_data.size = 0; return nSize; } -int udp_send(int nIndex, const uint8_t *pData, uint16_t nSize, uint32_t RemoteIp, uint16_t RemotePort) { - assert(nIndex >= 0); - assert(nIndex < UDP_MAX_PORTS_ALLOWED); - _pcast32 dst; - - if (__builtin_expect ((s_Port[nIndex] == 0), 0)) { - DEBUG_PUTS("ports_allowed[idx] == 0"); - return -1; - } - - if (RemoteIp == IPv4_BROADCAST) { - memset(s_send_packet.ether.dst, 0xFF, ETH_ADDR_LEN); - memset(s_send_packet.ip4.dst, 0xFF, IPv4_ADDR_LEN); - } else if ((RemoteIp & net::globals::nBroadcastMask) == net::globals::nBroadcastMask) { - memset(s_send_packet.ether.dst, 0xFF, ETH_ADDR_LEN); - dst.u32 = RemoteIp; - memcpy(s_send_packet.ip4.dst, dst.u8, IPv4_ADDR_LEN); - } else { - if ((RemoteIp & 0xE0) == 0xE0) { // Multicast, we know the MAC Address - _pcast32 multicast_ip; - - multicast_ip.u32 = RemoteIp; - - s_multicast_mac[3] = multicast_ip.u8[1] & 0x7F; - s_multicast_mac[4] = multicast_ip.u8[2]; - s_multicast_mac[5] = multicast_ip.u8[3]; - - memcpy(s_send_packet.ether.dst, s_multicast_mac, ETH_ADDR_LEN); - - dst.u32 = RemoteIp; - memcpy(s_send_packet.ip4.dst, dst.u8, IPv4_ADDR_LEN); - } else { - if (__builtin_expect((net::globals::nOnNetworkMask != (RemoteIp & net::globals::nOnNetworkMask)), 0)) { - if (net::globals::ipInfo.gw.addr == arp_cache_lookup(net::globals::ipInfo.gw.addr, s_send_packet.ether.dst)) { - dst.u32 = RemoteIp; - memcpy(s_send_packet.ip4.dst, dst.u8, IPv4_ADDR_LEN); - } else { -#ifndef NDEBUG - console_error("ARP lookup failed -> default gateway :"); - printf(IPSTR " [%d]\n", IP2STR(RemoteIp), s_Port[nIndex]); -#endif - return -3; - } - } else { - if (RemoteIp == arp_cache_lookup(RemoteIp, s_send_packet.ether.dst)) { - dst.u32 = RemoteIp; - memcpy(s_send_packet.ip4.dst, dst.u8, IPv4_ADDR_LEN); - } else { -#ifndef NDEBUG - console_error("ARP lookup failed: "); - printf(IPSTR "\n", IP2STR(RemoteIp)); -#endif - return -2; - } - } - } - } - - //IPv4 - s_send_packet.ip4.id = s_id; - s_send_packet.ip4.len = __builtin_bswap16((nSize + IPv4_UDP_HEADERS_SIZE)); - s_send_packet.ip4.chksum = 0; -#if !defined (CHECKSUM_BY_HARDWARE) - s_send_packet.ip4.chksum = net_chksum(reinterpret_cast(&s_send_packet.ip4), sizeof(s_send_packet.ip4)); -#endif - //UDP - s_send_packet.udp.source_port = __builtin_bswap16( s_Port[nIndex]); - s_send_packet.udp.destination_port = __builtin_bswap16(RemotePort); - s_send_packet.udp.len = __builtin_bswap16((nSize + UDP_HEADER_SIZE)); - - net_memcpy(s_send_packet.udp.data, pData, std::min(static_cast(UDP_DATA_SIZE), nSize)); - - emac_eth_send(reinterpret_cast(&s_send_packet), nSize + UDP_PACKET_HEADERS_SIZE); - - s_id++; - - return 0; +void udp_send(int nIndex, const uint8_t *pData, uint32_t nSize, uint32_t nRemoteIp, uint16_t nRemotePort) { + udp_send_implementation(nIndex, pData, nSize, nRemoteIp, nRemotePort); } +#if defined CONFIG_ENET_ENABLE_PTP +void udp_send_timestamp(int nIndex, const uint8_t *pData, uint32_t nSize, uint32_t nRemoteIp, uint16_t nRemotePort) { + udp_send_implementation(nIndex, pData, nSize, nRemoteIp, nRemotePort); +} +#endif +} // namespace net // <--- diff --git a/lib-network/src/params/networkparams.cpp b/lib-network/src/params/networkparams.cpp index 03d4eaf..76c9ebe 100644 --- a/lib-network/src/params/networkparams.cpp +++ b/lib-network/src/params/networkparams.cpp @@ -2,7 +2,7 @@ * @file networkparams.cpp * */ -/* Copyright (C) 2017-2023 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2017-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,7 @@ #include "networkparams.h" #include "networkparamsconst.h" + #include "readconfigfile.h" #include "sscan.h" @@ -45,7 +46,7 @@ using namespace networkparams; -NetworkParams::NetworkParams(NetworkParamsStore *pNetworkParamsStore): m_pNetworkParamsStore(pNetworkParamsStore) { +NetworkParams::NetworkParams() { DEBUG_ENTRY memset(&m_Params, 0, sizeof(struct networkparams::Params)); @@ -55,7 +56,7 @@ NetworkParams::NetworkParams(NetworkParamsStore *pNetworkParamsStore): m_pNetwor DEBUG_EXIT } -bool NetworkParams::Load() { +void NetworkParams::Load() { DEBUG_ENTRY m_Params.nSetList = 0; @@ -63,20 +64,15 @@ bool NetworkParams::Load() { ReadConfigFile configfile(NetworkParams::staticCallbackFunction, this); if (configfile.Read(NetworkParamsConst::FILE_NAME)) { - if (m_pNetworkParamsStore != nullptr) { - m_pNetworkParamsStore->Update(&m_Params); - } + NetworkParamsStore::Update(&m_Params); } else #endif - if (m_pNetworkParamsStore != nullptr) { - m_pNetworkParamsStore->Copy(&m_Params); - } else { - DEBUG_EXIT - return false; - } + NetworkParamsStore::Copy(&m_Params); +#ifndef NDEBUG + Dump(); +#endif DEBUG_EXIT - return true; } void NetworkParams::Load(const char *pBuffer, uint32_t nLength) { @@ -91,9 +87,11 @@ void NetworkParams::Load(const char *pBuffer, uint32_t nLength) { config.Read(pBuffer, nLength); - assert(m_pNetworkParamsStore != nullptr); - m_pNetworkParamsStore->Update(&m_Params); + NetworkParamsStore::Update(&m_Params); +#ifndef NDEBUG + Dump(); +#endif DEBUG_EXIT } @@ -145,8 +143,13 @@ void NetworkParams::callbackFunction(const char *pLine) { } if (Sscan::IpAddress(pLine, NetworkParamsConst::DEFAULT_GATEWAY, nValue32) == Sscan::OK) { - m_Params.nGatewayIp = nValue32; - m_Params.nSetList |= networkparams::Mask::DEFAULT_GATEWAY; + if (nValue32 != 0) { + m_Params.nSetList |= networkparams::Mask::DEFAULT_GATEWAY; + m_Params.nGatewayIp = nValue32; + } else { + m_Params.nSetList &= ~networkparams::Mask::DEFAULT_GATEWAY; + } + return; } @@ -158,8 +161,6 @@ void NetworkParams::callbackFunction(const char *pLine) { return; } - -#if !defined(DISABLE_RTC) if (Sscan::IpAddress(pLine, NetworkParamsConst::NTP_SERVER, nValue32) == Sscan::OK) { if (nValue32 != 0) { m_Params.nSetList |= networkparams::Mask::NTP_SERVER; @@ -170,21 +171,6 @@ void NetworkParams::callbackFunction(const char *pLine) { return; } - float fValue; - - if (Sscan::Float(pLine, NetworkParamsConst::NTP_UTC_OFFSET, fValue) == Sscan::OK) { - // https://en.wikipedia.org/wiki/List_of_UTC_time_offsets - if ((static_cast(fValue) >= -12) && (static_cast(fValue) <= 14) && (static_cast(fValue) != 0)) { - m_Params.fNtpUtcOffset = fValue; - m_Params.nSetList |= networkparams::Mask::NTP_UTC_OFFSET; - } else { - m_Params.fNtpUtcOffset = 0; - m_Params.nSetList &= ~networkparams::Mask::NTP_UTC_OFFSET; - } - return; - } -#endif - #if defined (ESP8266) if (Sscan::IpAddress(pLine, NetworkParamsConst::NAME_SERVER, nValue32) == Sscan::OK) { m_Params.nNameServerIp = nValue32; @@ -223,8 +209,7 @@ void NetworkParams::Builder(const struct networkparams::Params *ptNetworkParams, if (ptNetworkParams != nullptr) { memcpy(&m_Params, ptNetworkParams, sizeof(struct networkparams::Params)); } else { - assert(m_pNetworkParamsStore != nullptr); - m_pNetworkParamsStore->Copy(&m_Params); + NetworkParamsStore::Copy(&m_Params); } PropertiesBuilder builder(NetworkParamsConst::FILE_NAME, pBuffer, nLength); @@ -259,14 +244,27 @@ void NetworkParams::Builder(const struct networkparams::Params *ptNetworkParams, #endif builder.Add(NetworkParamsConst::HOSTNAME, m_Params.aHostName, isMaskSet(networkparams::Mask::HOSTNAME)); -#if !defined(DISABLE_RTC) builder.AddComment("NTP Server"); builder.AddIpAddress(NetworkParamsConst::NTP_SERVER, m_Params.nNtpServerIp, isMaskSet(networkparams::Mask::NTP_SERVER)); - builder.Add(NetworkParamsConst::NTP_UTC_OFFSET, m_Params.fNtpUtcOffset, isMaskSet(networkparams::Mask::NTP_UTC_OFFSET)); -#endif nSize = builder.GetSize(); DEBUG_PRINTF("nSize=%d", nSize); DEBUG_EXIT } + +void NetworkParams::Dump() { + printf("%s::%s \'%s\':\n", __FILE__, __FUNCTION__, NetworkParamsConst::FILE_NAME); + + printf(" %s=%d [%s]\n", NetworkParamsConst::USE_DHCP, static_cast(m_Params.bIsDhcpUsed), m_Params.bIsDhcpUsed != 0 ? "Yes" : "No"); + printf(" %s=" IPSTR "\n", NetworkParamsConst::IP_ADDRESS, IP2STR(m_Params.nLocalIp)); + printf(" %s=" IPSTR "\n", NetworkParamsConst::NET_MASK, IP2STR(m_Params.nNetmask)); + printf(" %s=" IPSTR "\n", NetworkParamsConst::DEFAULT_GATEWAY, IP2STR(m_Params.nGatewayIp)); + +#if defined (ESP8266) + printf(" %s=" IPSTR "\n", NetworkParamsConst::NAME_SERVER, IP2STR(m_Params.nNameServerIp)); +#endif + + printf(" %s=%s\n", NetworkParamsConst::HOSTNAME, m_Params.aHostName); + printf(" %s=" IPSTR "\n", NetworkParamsConst::NTP_SERVER, IP2STR(m_Params.nNtpServerIp)); +} diff --git a/lib-network/src/networkparamsconst.cpp b/lib-network/src/params/networkparamsconst.cpp old mode 100644 new mode 100755 similarity index 93% rename from lib-network/src/networkparamsconst.cpp rename to lib-network/src/params/networkparamsconst.cpp index 5081187..ae28a8d --- a/lib-network/src/networkparamsconst.cpp +++ b/lib-network/src/params/networkparamsconst.cpp @@ -2,7 +2,7 @@ * @file networkparamsconst.cpp * */ -/* Copyright (C) 2021 by Arjan van Vught mailto:info@orangepi-dmx.nl +/* Copyright (C) 2021-2024 by Arjan van Vught mailto:info@gd32-dmx.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,6 @@ const char NetworkParamsConst::DEFAULT_GATEWAY[] = "default_gateway"; const char NetworkParamsConst::HOSTNAME[] = "hostname"; const char NetworkParamsConst::NTP_SERVER[] = "ntp_server"; -const char NetworkParamsConst::NTP_UTC_OFFSET[] = "ntp_utc_offset"; #if defined (ESP8266) const char NetworkParamsConst::NAME_SERVER[] = "name_server"; diff --git a/lib-network/src/params/networkparamsdump.cpp b/lib-network/src/params/networkparamsdump.cpp deleted file mode 100644 index ada0652..0000000 --- a/lib-network/src/params/networkparamsdump.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file networkparamsdump.cpp - * - */ -/* Copyright (C) 2020 by Arjan van Vught mailto:info@orangepi-dmx.nl - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#if !defined(__clang__) // Needed for compiling on MacOS -# pragma GCC push_options -# pragma GCC optimize ("Os") -#endif - -#include - -#include "network.h" -#include "networkparams.h" -#include "networkparamsconst.h" - -#include "debug.h" - -void NetworkParams::Dump() { -#ifndef NDEBUG - printf("%s::%s \'%s\':\n", __FILE__, __FUNCTION__, NetworkParamsConst::FILE_NAME); - - debug_print_bits(m_Params.nSetList); - - printf(" %s=%d [%s]\n", NetworkParamsConst::USE_DHCP, static_cast(m_Params.bIsDhcpUsed), m_Params.bIsDhcpUsed != 0 ? "Yes" : "No"); - printf(" %s=" IPSTR "\n", NetworkParamsConst::IP_ADDRESS, IP2STR(m_Params.nLocalIp)); - printf(" %s=" IPSTR "\n", NetworkParamsConst::NET_MASK, IP2STR(m_Params.nNetmask)); - -#if defined (ESP8266) - printf(" %s=" IPSTR "\n", NetworkParamsConst::DEFAULT_GATEWAY, IP2STR(m_Params.nGatewayIp)); - printf(" %s=" IPSTR "\n", NetworkParamsConst::NAME_SERVER, IP2STR(m_Params.nNameServerIp)); -#endif - - printf(" %s=%s\n", NetworkParamsConst::HOSTNAME, m_Params.aHostName); - printf(" %s=" IPSTR "\n", NetworkParamsConst::NTP_SERVER, IP2STR(m_Params.nNtpServerIp)); - printf(" %s=%1.1f\n", NetworkParamsConst::NTP_UTC_OFFSET, m_Params.fNtpUtcOffset); -#endif -} diff --git a/lib-properties/.cproject b/lib-properties/.cproject index 83e1d5e..c5d82c2 100755 --- a/lib-properties/.cproject +++ b/lib-properties/.cproject @@ -24,7 +24,6 @@