initial commit
This commit is contained in:
commit
fe64f5342d
865
CMSIS/cmsis_armcc.h
Normal file
865
CMSIS/cmsis_armcc.h
Normal file
@ -0,0 +1,865 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 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_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 */
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
/* ########################### 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 the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __enable_irq(); */
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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 the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable FIQ
|
||||
\details 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
|
||||
\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 */
|
||||
|
||||
|
||||
/* ########################## 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() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\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() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\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() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
|
||||
/**
|
||||
\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 */
|
||||
|
||||
|
||||
/* ################### 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))
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
1869
CMSIS/cmsis_armclang.h
Normal file
1869
CMSIS/cmsis_armclang.h
Normal file
File diff suppressed because it is too large
Load Diff
266
CMSIS/cmsis_compiler.h
Normal file
266
CMSIS/cmsis_compiler.h
Normal file
@ -0,0 +1,266 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 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 <stdint.h>
|
||||
|
||||
/*
|
||||
* Arm Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Arm Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include <cmsis_iccarm.h>
|
||||
|
||||
|
||||
/*
|
||||
* TI Arm Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#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
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
2085
CMSIS/cmsis_gcc.h
Normal file
2085
CMSIS/cmsis_gcc.h
Normal file
File diff suppressed because it is too large
Load Diff
935
CMSIS/cmsis_iccarm.h
Normal file
935
CMSIS/cmsis_iccarm.h
Normal file
@ -0,0 +1,935 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
|
||||
* @version V5.0.7
|
||||
* @date 19. June 2018
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2018 IAR Systems
|
||||
//
|
||||
// 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 __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
|
||||
#define __RESTRICT __restrict
|
||||
#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
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#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)))
|
||||
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
|
||||
#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"))
|
||||
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
|
||||
#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 <intrinsics.h>
|
||||
|
||||
#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("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
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_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("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("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("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM("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
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
39
CMSIS/cmsis_version.h
Normal file
39
CMSIS/cmsis_version.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 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 ( 1U) /*!< [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
|
949
CMSIS/core_cm0.h
Normal file
949
CMSIS/core_cm0.h
Normal file
@ -0,0 +1,949 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.5
|
||||
* @date 28. May 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.
|
||||
*/
|
||||
|
||||
#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_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M0
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< 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_PCS_VFP
|
||||
#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_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000U
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#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
|
||||
|
||||
<strong>IO Type Qualifiers</strong> 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_M0 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick 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:28; /*!< bit: 0..27 Reserved */
|
||||
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 */
|
||||
|
||||
|
||||
/**
|
||||
\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:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
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_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved0:1; /*!< bit: 0 Reserved */
|
||||
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 */
|
||||
|
||||
/*@} 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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} 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 */
|
||||
uint32_t RESERVED0;
|
||||
__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 */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE 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_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 */
|
||||
|
||||
/* 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_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 */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\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_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} 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 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 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 */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick 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 not available for Cortex-M0 */
|
||||
#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 */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\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)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (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.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\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 *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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 *)0x0U;
|
||||
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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## 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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
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, 1); /* 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 */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
10677
CMSIS/stm32f042x6.h
Normal file
10677
CMSIS/stm32f042x6.h
Normal file
File diff suppressed because it is too large
Load Diff
103
CMSIS/system_stm32f0xx.h
Normal file
103
CMSIS/system_stm32f0xx.h
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f0xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M0 Device System Source File for STM32F0xx devices.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f0xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef __SYSTEM_STM32F0XX_H
|
||||
#define __SYSTEM_STM32F0XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
3) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) by calling HAL API function HAL_RCC_ClockConfig()
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
extern const uint16_t AHBPrescTable[16]; /*!< AHB prescalers table values */
|
||||
extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F0xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SYSTEM_STM32F0XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
320
adc.c
Normal file
320
adc.c
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* @file adc.c
|
||||
* @date Mar 14, 2024
|
||||
* @author Francesco Gritti
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
#ifdef use_adc
|
||||
|
||||
void ADC_COMP_IRQHandler (void) {
|
||||
|
||||
|
||||
if ((ADC1->ISR & ADC_ISR_OVR) != 0) {
|
||||
|
||||
ADC1->ISR |= ADC_ISR_OVR; // clear interrupt flag
|
||||
ADC1->CR &= ~ADC_CR_ADSTART; // stop ADC
|
||||
}
|
||||
|
||||
else if ((ADC1->ISR & ADC_ISR_EOS) != 0) {
|
||||
|
||||
ADC1->ISR |= ADC_ISR_EOS;
|
||||
flib_printf ("conv end\n");
|
||||
}
|
||||
|
||||
else if ((ADC1->ISR & ADC_ISR_EOC) != 0) {
|
||||
|
||||
ADC1->ISR |= ADC_ISR_EOC;
|
||||
|
||||
u32 adcVal = ADC1->DR;
|
||||
|
||||
flib_printf ("conv\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NOTE: in case of ADC overrun error, the ADC is stopped and must
|
||||
// be re-initalized by clearing OVR flag.
|
||||
// when all data requested to the DMA have been transferred, the ADC
|
||||
// is automatically stopped
|
||||
|
||||
|
||||
|
||||
void ADC_init (void) {
|
||||
|
||||
// enable DMA and ADC clock
|
||||
RCC_ADC_CLK_ENABLE();
|
||||
|
||||
// NOTE: must clear ADSTART bit to set some registers
|
||||
ADC1->CR = 0x0000;
|
||||
ADC1->CFGR2 = (ADC_CLK << ADC_CFGR2_CKMODE_Pos);
|
||||
ADC1->CFGR1 = (ADC_CONV_MODE << ADC_CFGR1_CONT_Pos) |
|
||||
(ADC_OVRMOD << ADC_CFGR1_OVRMOD_Pos) |
|
||||
(ADC_EXTEN_EDGE << ADC_CFGR1_EXTEN_Pos) |
|
||||
(ADC_EXTSEL << ADC_CFGR1_EXTSEL_Pos) |
|
||||
(ADC_ALIGN_RIGHT << ADC_CFGR1_ALIGN_Pos) |
|
||||
(ADC_RES_12bit << ADC_CFGR1_RES_Pos);
|
||||
|
||||
|
||||
// enable end of sequence and end of conversion interrupt
|
||||
ADC1->IER = ADC_IER_EOCIE | ADC_IER_EOSIE;
|
||||
ADC1->SMPR = (ADC_SAMPLE_TIME << ADC_SMPR_SMP_Pos);
|
||||
|
||||
|
||||
// enable interrupt
|
||||
NVIC_EnableIRQ(ADC1_IRQn);
|
||||
NVIC_SetPriority(ADC1_IRQn, 2);
|
||||
|
||||
ADC1->CR |= ADC_CR_ADEN_Msk;
|
||||
// wait until ADC is ready for conversion
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ADC_StartConversion (void) {
|
||||
|
||||
ADC1->CR |= ADC_CR_ADSTART;
|
||||
}
|
||||
|
||||
|
||||
void ADC_addChannelToScanList (u8 channel) {
|
||||
ADC1->CHSELR |= (1<<channel);
|
||||
}
|
||||
|
||||
void ADC_removeChannelFromScanList (u8 channel) {
|
||||
ADC1->CHSELR &= ~(1<<channel);
|
||||
}
|
||||
|
||||
// configure DMA and start conversion
|
||||
void ADC_startConversionDMA (u8 channels, u16 * ADC_array) {
|
||||
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
|
||||
DMA1_Channel1->CNDTR = channels;
|
||||
|
||||
ADC1->CR |= ADC_CR_ADSTART; // start converting and generating DMA requests
|
||||
}
|
||||
|
||||
// configure DMA only. Conversion will be triggered lately by software or by hardware
|
||||
// through an event
|
||||
void ADC_configureDMA (u8 channels, u16 * ADC_array) {
|
||||
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
|
||||
DMA1_Channel1->CNDTR = channels;
|
||||
}
|
||||
|
||||
u8 ADC_disable (void) {
|
||||
|
||||
ADC1->CR |= ADC_CR_ADDIS_Msk;
|
||||
|
||||
// wait until ADC is actually disabled
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->CR & ADC_CR_ADDIS_Msk) != 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 ADC_enable (void) {
|
||||
|
||||
ADC1->CR |= ADC_CR_ADEN_Msk;
|
||||
// wait until ADC is ready for conversion
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef use_adc_dma
|
||||
|
||||
|
||||
|
||||
__attribute__((weak)) void adc_dma_transferCompleteCallback (void) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
__attribute__((weak)) void adc_dma_halfTransferCallback (void) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DMA1_CH1_IRQHandler (void) {
|
||||
|
||||
|
||||
if ((DMA1->ISR & DMA_ISR_GIF1) != 0) {
|
||||
|
||||
// check for transfer complete
|
||||
if ((DMA1->ISR & DMA_ISR_TCIF1) != 0) {
|
||||
DMA1->IFCR |= DMA_IFCR_CTCIF1;
|
||||
|
||||
DMA1_Channel1->CCR &= ~DMA_CCR_EN; // disable DMA channel
|
||||
|
||||
adc_dma_transferCompleteCallback ();
|
||||
}
|
||||
|
||||
// transfer half complete
|
||||
else if ((DMA1->ISR & DMA_ISR_HTIF1) != 0) {
|
||||
DMA1->IFCR |= DMA_IFCR_CHTIF1;
|
||||
|
||||
adc_dma_halfTransferCallback ();
|
||||
}
|
||||
|
||||
// error flag
|
||||
else if ((DMA1->ISR & DMA_ISR_TEIF1) != 0) {
|
||||
|
||||
|
||||
// channel EN bit automatically cleared on DMA error
|
||||
// cannot re-enable DMA channel before clearing error flag
|
||||
DMA1->IFCR |= DMA_IFCR_CTEIF1;
|
||||
|
||||
// re-init ADC peripheral. Wait for software to call again acquisition
|
||||
ADC_init ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ADC_COMP_IRQHandler (void) {
|
||||
|
||||
|
||||
if ((ADC1->ISR & ADC_ISR_OVR) != 0) {
|
||||
|
||||
ADC1->ISR |= ADC_ISR_OVR; // clear interrupt flag
|
||||
ADC1->CR &= ~ADC_CR_ADSTART; // stop ADC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NOTE: in case of ADC overrun error, the ADC is stopped and must
|
||||
// be re-initalized by clearing OVR flag.
|
||||
// when all data requested to the DMA have been transferred, the ADC
|
||||
// is automatically stopped
|
||||
|
||||
|
||||
|
||||
void ADC_init (void) {
|
||||
|
||||
// enable DMA and ADC clock
|
||||
RCC_DMA_CLK_ENABLE();
|
||||
RCC_ADC_CLK_ENABLE();
|
||||
|
||||
// NOTE: must clear ADSTART bit to set some registers
|
||||
ADC1->CR = 0x0000;
|
||||
ADC1->CFGR2 = (ADC_CLK << ADC_CFGR2_CKMODE_Pos);
|
||||
ADC1->CFGR1 = (ADC_CONV_MODE << ADC_CFGR1_CONT_Pos) |
|
||||
(ADC_OVRMOD << ADC_CFGR1_OVRMOD_Pos) |
|
||||
(ADC_EXTEN_EDGE << ADC_CFGR1_EXTEN_Pos) |
|
||||
(ADC_EXTSEL << ADC_CFGR1_EXTSEL_Pos) |
|
||||
(ADC_ALIGN_RIGHT << ADC_CFGR1_ALIGN_Pos) |
|
||||
(ADC_RES_12bit << ADC_CFGR1_RES_Pos) |
|
||||
(ADC_DMA_MODE << ADC_CFGR1_DMACFG_Pos) |
|
||||
(ADC_DMA_EN << ADC_CFGR1_DMAEN_Pos);
|
||||
|
||||
|
||||
// disable all interrupt, it will be called by the DMA on transaction completed
|
||||
ADC1->IER = 0x00;
|
||||
|
||||
ADC1->SMPR = (ADC_SAMPLE_TIME << ADC_SMPR_SMP_Pos);
|
||||
|
||||
// configure DMA, enabled error, complete interrupts
|
||||
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
|
||||
DMA1_Channel1->CCR |= DMA_CCR_MINC | (DMA_MSIZE_16_bit << DMA_CCR_MSIZE_Pos) | (DMA_PSIZE_16_bit << DMA_CCR_PSIZE_Pos) |
|
||||
DMA_CCR_TEIE | DMA_CCR_TCIE ;
|
||||
|
||||
// enable DMA interrupt needed for errors and transfer complete
|
||||
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
NVIC_SetPriority(DMA1_Channel1_IRQn, 2);
|
||||
|
||||
// enable ADC interrupt needed to detect overrun error and
|
||||
// in that case to restart the ADC peripheral
|
||||
//NVIC_EnableIRQ(ADC1_IRQn);
|
||||
//NVIC_SetPriority(ADC1_IRQn, 2);
|
||||
|
||||
ADC1->CR |= ADC_CR_ADEN_Msk;
|
||||
// wait until ADC is ready for conversion
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ADC_addChannelToScanList (u8 channel) {
|
||||
ADC1->CHSELR |= (1<<channel);
|
||||
}
|
||||
|
||||
void ADC_removeChannelFromScanList (u8 channel) {
|
||||
ADC1->CHSELR &= ~(1<<channel);
|
||||
}
|
||||
|
||||
// configure DMA and start conversion
|
||||
void ADC_startConversionDMA (u8 channels, u16 * ADC_array) {
|
||||
|
||||
DMA1_Channel1->CCR &= ~DMA_CCR_EN; // disable DMA channel
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
|
||||
DMA1_Channel1->CNDTR = channels;
|
||||
DMA1_Channel1->CCR |= DMA_CCR_EN; // enable DMA
|
||||
|
||||
ADC1->CR |= ADC_CR_ADSTART; // start converting and generating DMA requests
|
||||
}
|
||||
|
||||
// configure DMA only. Conversion will be triggered lately by software or by hardware
|
||||
// through an event
|
||||
void ADC_configureDMA (u8 channels, u16 * ADC_array) {
|
||||
|
||||
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
|
||||
DMA1_Channel1->CNDTR = channels;
|
||||
}
|
||||
|
||||
u8 ADC_disable (void) {
|
||||
|
||||
ADC1->CR |= ADC_CR_ADDIS_Msk;
|
||||
|
||||
// wait until ADC is actually disabled
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->CR & ADC_CR_ADDIS_Msk) != 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 ADC_enable (void) {
|
||||
|
||||
ADC1->CR |= ADC_CR_ADEN_Msk;
|
||||
// wait until ADC is ready for conversion
|
||||
u32 startTick = flib_GetTick();
|
||||
while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
735
can.c
Normal file
735
can.c
Normal file
@ -0,0 +1,735 @@
|
||||
/*!
|
||||
* @file can.c
|
||||
* @author Francesco Gritti
|
||||
* @brief can peripheral driver implementation
|
||||
*
|
||||
* This files implements all CAN bus funcitonalities
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
#ifdef use_can
|
||||
|
||||
#include "can.h"
|
||||
#include <fifo.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
|
||||
//#define CAN_IMPLEMENT_FIFO
|
||||
//#define CAN_FIFO_DEPTH
|
||||
#define CAN_MINIMAL_IMPLEMENTATION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* CAN bus Flasher
|
||||
|
||||
- flashare il mcu con del nuovo codice dalla periferica can bus.
|
||||
- funzionare correttamente con altri dispositivi connessi al bus
|
||||
- error detection / retransmission
|
||||
|
||||
|
||||
STRUTTURA CODICE
|
||||
|
||||
- è necessario che TUTTO il codice eseguito durante la fase di programmazione sia
|
||||
caricato in RAM => Anche l' Interrupt Handler, il codice per inviare dati sul CAN
|
||||
e qualsiasi di queste cose. Durante la fase di programmazione è fondamentale
|
||||
assicurarsi che non vengano lanciati interrupt o altro da periferiche (a parte il CAN)
|
||||
=> DISABILITO INTERRUPT QUANDO ENTRO IN ROUTINE PROGRAMMAZIONE
|
||||
|
||||
|
||||
PROCEDURA
|
||||
|
||||
|
||||
1) il rpogrammatore invia il comando PROGRAMMING_INIT con payload l'ID
|
||||
del dispositivo che si vuole riprogrammare
|
||||
|
||||
2) Il dispositivo corrispondente entra nella routine can_flasher_SRAM
|
||||
mentre tutti gli altri smettono di inviare comandi sul can bus dal
|
||||
momento che questo potrebbe interferire o rallentare la procedura di
|
||||
caricamento del nuovo firmware
|
||||
|
||||
3) il programmatore invia ogni un pacchetto da 8 byte alla volta e attende
|
||||
l'ACK del dispositivo che si sta riprogrammando. Questo è necessario
|
||||
poichè lo standard CAN richiede che ogni dispositivo connesso alla rete
|
||||
invii un messaggio di acknowledge quando riceve un messaggio con CRC corretto,
|
||||
anche se non è tra i suoi filtri.
|
||||
|
||||
3-b) in caso di errore, sia che venga ricevuto un NACK al messaggio CAN,
|
||||
sia che NON venga ricevuto alcun messaggio da parte del sispositivo
|
||||
in programmazione si prova a reinviare il blocco dati per un numero N
|
||||
di volte
|
||||
|
||||
4) una volta inviato l'intero firmware, il programmator einvia il comando
|
||||
PROGRAMMING_EXIT con cui notifica al dispositivo di resettarsi e a tutti
|
||||
gli altri di riprendere le loro normali funzioni
|
||||
|
||||
* */
|
||||
|
||||
|
||||
|
||||
#ifdef CAN_IMPLEMENT_FIFO
|
||||
FIFO_CREATE(canMessage_t, CAN_TxFIFO, CAN_FIFO_DEPTH);
|
||||
#endif
|
||||
|
||||
|
||||
/* Static functions */
|
||||
static u8 s_mailbox_transmit (u8 mbx, u16 ID, u8 * data, u8 len, canIdExtension idType, canDataRemote dataRemote);
|
||||
static u8 s_abort_mailbox_transmit (u8 mbx);
|
||||
static void s_can_read_message (u8 mailbox);
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__ ((weak)) void CAN_TxOverride (void) {}
|
||||
__attribute__ ((weak)) void CAN_busError (void) {}
|
||||
__attribute__ ((weak)) void CAN_onNACK (canMessage_t *message) {(void) message;}
|
||||
__attribute__ ((weak)) void can_message_received (canMessage_t *message) {(void) message;}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
canNetworkStatus_t can_get_network_status () {
|
||||
|
||||
canNetworkStatus_t netStat = {
|
||||
.TEC = (CAN->ESR & CAN_ESR_TEC_Msk) >> CAN_ESR_TEC_Pos,
|
||||
.REC = (CAN->ESR & CAN_ESR_REC_Msk) >> CAN_ESR_REC_Pos,
|
||||
.error_warning = (CAN->ESR & CAN_ESR_BOFF_Msk)>> CAN_ESR_BOFF_Pos,
|
||||
.error_passive = (CAN->ESR & CAN_ESR_EPVF_Msk)>> CAN_ESR_EPVF_Pos,
|
||||
.bus_off = (CAN->ESR & CAN_ESR_EWGF_Msk)>> CAN_ESR_EWGF_Pos,
|
||||
.LEC = (CAN->ESR & CAN_ESR_LEC_Msk) >> CAN_ESR_LEC_Pos,
|
||||
};
|
||||
return netStat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CEC_CAN_IRQHandler (void) {
|
||||
|
||||
|
||||
// check if there are messages to be read in FIFO0 and FIFO1
|
||||
u8 nMessagesFIFO0 = (CAN->RF0R & CAN_RF0R_FMP0_Msk) >> CAN_RF0R_FMP0_Pos;
|
||||
u8 nMessagesFIFO1 = (CAN->RF1R & CAN_RF1R_FMP1_Msk) >> CAN_RF1R_FMP1_Pos;
|
||||
|
||||
for (; nMessagesFIFO0>0; nMessagesFIFO0--) {
|
||||
s_can_read_message (0);
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
for (; nMessagesFIFO1>0; nMessagesFIFO1--) {
|
||||
s_can_read_message (1);
|
||||
CAN->RF1R |= CAN_RF1R_RFOM1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CAN_IMPLEMENT_FIFO
|
||||
|
||||
// check if one of the mailbox has completed transmission
|
||||
if ((CAN->TSR & (CAN_TSR_TXOK0 | CAN_TSR_TXOK1 | CAN_TSR_TXOK2)) != 0) {
|
||||
|
||||
// clear all mailboxes status flag
|
||||
CAN->TSR |= CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2;
|
||||
|
||||
if (!FIFO_isEmpty (&CAN_TxFIFO)) {
|
||||
// get the message from FIFO
|
||||
canMessage_t *message = (canMessage_t*) FIFO_Pop (&CAN_TxFIFO);
|
||||
// make sure pointer is valid
|
||||
if (message != 0) {
|
||||
|
||||
u8 mbxCode = (CAN->TSR & (CAN_TSR_CODE_Msk)) >> CAN_TSR_CODE_Pos;
|
||||
// make sure that a mailbox is actually free. If it is, it is the one identified
|
||||
// by mbxCode
|
||||
if ((CAN->TSR & (CAN_TSR_TME0_Msk | CAN_TSR_TME1_Msk | CAN_TSR_TME2_Msk)) != 0) {
|
||||
|
||||
s_mailbox_transmit (mbxCode,message->id, message->data, message->data_len, message->std_ext_id, message->data_remote_frame);
|
||||
}
|
||||
else {
|
||||
FIFO_Append (&CAN_TxFIFO, (u8*)message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void s_can_read_message (u8 mailbox) {
|
||||
|
||||
canMessage_t rxMessage;
|
||||
rxMessage.std_ext_id = (CAN->sFIFOMailBox[mailbox].RIR & CAN_RI0R_IDE) != 0;
|
||||
rxMessage.data_remote_frame = (CAN->sFIFOMailBox[mailbox].RIR & CAN_RI0R_RTR) != 0;
|
||||
rxMessage.id = (rxMessage.std_ext_id == canSTD_ID ? (CAN->sFIFOMailBox[mailbox].RIR & CAN_RI0R_STID) >> CAN_RI0R_STID_Pos :
|
||||
(CAN->sFIFOMailBox[mailbox].RIR & CAN_RI0R_EXID) >> CAN_RI0R_EXID_Pos);
|
||||
|
||||
rxMessage.data_len = (CAN->sFIFOMailBox[mailbox].RDTR & CAN_RDT0R_DLC_Msk) >> CAN_RDT0R_DLC_Pos;
|
||||
|
||||
rxMessage.data [0] = (CAN->sFIFOMailBox[mailbox].RDLR & CAN_RDL0R_DATA0) >> CAN_RDL0R_DATA0_Pos;
|
||||
rxMessage.data [1] = (CAN->sFIFOMailBox[mailbox].RDLR & CAN_RDL0R_DATA1) >> CAN_RDL0R_DATA1_Pos;
|
||||
rxMessage.data [2] = (CAN->sFIFOMailBox[mailbox].RDLR & CAN_RDL0R_DATA2) >> CAN_RDL0R_DATA2_Pos;
|
||||
rxMessage.data [3] = (CAN->sFIFOMailBox[mailbox].RDLR & CAN_RDL0R_DATA3) >> CAN_RDL0R_DATA3_Pos;
|
||||
|
||||
rxMessage.data [4] = (CAN->sFIFOMailBox[mailbox].RDHR & CAN_RDH0R_DATA4) >> CAN_RDH0R_DATA4_Pos;
|
||||
rxMessage.data [5] = (CAN->sFIFOMailBox[mailbox].RDHR & CAN_RDH0R_DATA5) >> CAN_RDH0R_DATA5_Pos;
|
||||
rxMessage.data [6] = (CAN->sFIFOMailBox[mailbox].RDHR & CAN_RDH0R_DATA6) >> CAN_RDH0R_DATA6_Pos;
|
||||
rxMessage.data [7] = (CAN->sFIFOMailBox[mailbox].RDHR & CAN_RDH0R_DATA7) >> CAN_RDH0R_DATA7_Pos;
|
||||
can_message_received (&rxMessage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i8 can_init (void) {
|
||||
|
||||
RCC_CAN1_CLK_ENABLE();
|
||||
|
||||
// configure GPIO
|
||||
GPIO_AF_PP (CAN_TX);
|
||||
GPIO_AF_PP (CAN_RX);
|
||||
GPIO_SET_AFRH (CAN_TX, 0x04);
|
||||
GPIO_SET_AFRH (CAN_RX, 0x04);
|
||||
|
||||
|
||||
// enter initialization mode
|
||||
u32 startTick = flib_GetTick();
|
||||
CAN->MCR |= CAN_MCR_INRQ;
|
||||
|
||||
// wait 10ms for the CAN peripheral to enter initialization mode
|
||||
// otherwise, return error
|
||||
while ((CAN->MSR & CAN_MSR_INAK) == 0U) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return CAN_INIT_ERROR;
|
||||
}
|
||||
CAN->MCR &= ~CAN_MCR_SLEEP;
|
||||
//CAN_BTR_LBKM
|
||||
CAN->BTR = ((CAN_SJW-1) << CAN_BTR_SJW_Pos) | ((CAN_SEG2-1) << CAN_BTR_TS2_Pos) | ((CAN_SEG1-1) << CAN_BTR_TS1_Pos) | ((CAN_PRESCALER-1) << CAN_BTR_BRP_Pos);
|
||||
|
||||
// enable interrupt on error and on FIFO 0/1 not empty and TX request complete (abort or transmit)
|
||||
CAN->IER = CAN_IER_ERRIE | CAN_IER_FMPIE1 | CAN_IER_FMPIE0 | CAN_IER_TMEIE;
|
||||
//CAN->MSR |= CAN_MSR_ERRI;
|
||||
|
||||
// enable interrupt request
|
||||
NVIC_SetPriority(CEC_CAN_IRQn, 2);
|
||||
NVIC_EnableIRQ(CEC_CAN_IRQn);
|
||||
|
||||
// enter normal mode. Do not wait for peripheral acknowledge since if there
|
||||
// are transmissions going on on the bus it might take a while for the
|
||||
// peripheral to enter normal mode and it is not necessary to wait
|
||||
CAN->MCR &= ~CAN_MCR_INRQ;
|
||||
|
||||
return CAN_INIT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void can_init_minimal (void) {
|
||||
|
||||
RCC_CAN1_CLK_ENABLE();
|
||||
|
||||
// configure GPIO
|
||||
GPIO_AF_PP (CAN_TX);
|
||||
GPIO_AF_PP (CAN_RX);
|
||||
GPIO_SET_AFRH (CAN_TX, 0x04);
|
||||
GPIO_SET_AFRH (CAN_RX, 0x04);
|
||||
|
||||
|
||||
CAN->MCR |= CAN_MCR_INRQ;
|
||||
|
||||
while ((CAN->MSR & CAN_MSR_INAK) == 0U);
|
||||
CAN->MCR &= ~CAN_MCR_SLEEP;
|
||||
//CAN_BTR_LBKM
|
||||
CAN->BTR = ((CAN_SJW-1) << CAN_BTR_SJW_Pos) | ((CAN_SEG2-1) << CAN_BTR_TS2_Pos) | ((CAN_SEG1-1) << CAN_BTR_TS1_Pos) | ((CAN_PRESCALER-1) << CAN_BTR_BRP_Pos);
|
||||
|
||||
// enable interrupt on error and on FIFO 0/1 not empty and TX request complete (abort or transmit)
|
||||
CAN->IER = CAN_IER_ERRIE | CAN_IER_FMPIE1 | CAN_IER_FMPIE0 | CAN_IER_TMEIE;
|
||||
|
||||
// enable interrupt request
|
||||
NVIC_SetPriority(CEC_CAN_IRQn, 2);
|
||||
NVIC_EnableIRQ(CEC_CAN_IRQn);
|
||||
|
||||
CAN->MCR &= ~CAN_MCR_INRQ;
|
||||
// wait for peripheral to enter normal mode
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i8 can_transmit_f32 (u16 ID, f32 data, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override) {
|
||||
|
||||
f32 localData = data;
|
||||
u8 *buffer = (u8*) (&localData);
|
||||
return can_transmit (ID, buffer, 4, idType, dataRemote, override);
|
||||
}
|
||||
|
||||
|
||||
i8 can_transmit_u32 (u16 ID, u32 data, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override) {
|
||||
|
||||
u32 localData = data;
|
||||
u8 *buffer = (u8*) (&localData);
|
||||
return can_transmit (ID, buffer, 4, idType, dataRemote, override);
|
||||
}
|
||||
|
||||
f32 can_extract_f32 (u8 *payload) {
|
||||
|
||||
f32* data = (f32*) (payload);
|
||||
return *data;
|
||||
}
|
||||
u32 can_extract_u32 (u8 *payload) {
|
||||
|
||||
u32* data = (u32*) (payload);
|
||||
return *data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// with 16bit registers only STD IDs can be mapped
|
||||
u8 can_config_filter_mask_mode_16bit (u8 filterId, canFIFO assignedFIFO, canDataRemote dataRemote, u16 id1, u16 id2, u16 mask1, u16 mask2) {
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return 0;
|
||||
|
||||
u32 filterBitMask = (u32)(1 << filterId);
|
||||
|
||||
// deactivate filter
|
||||
CAN->FA1R &= ~filterBitMask;
|
||||
// enter filter configuration mode
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
// set mask mode
|
||||
CAN->FM1R &= ~ filterBitMask;
|
||||
// set scale mode to 16 bit
|
||||
CAN->FS1R &= ~ filterBitMask;
|
||||
|
||||
|
||||
u32 mask1_reg = ((u32)mask1 << 5);
|
||||
u32 id1_reg = ((u32) id1 << 5);
|
||||
u32 mask2_reg = ((u32)mask2 << 5);
|
||||
u32 id2_reg = ((u32) id2 << 5);
|
||||
if (dataRemote == canREMOTE_FRAME) {
|
||||
mask1_reg |= (1 << 4);
|
||||
id1_reg |= (1 << 4);
|
||||
mask2_reg |= (1 << 4);
|
||||
id2_reg |= (1 << 4);
|
||||
}
|
||||
|
||||
CAN->sFilterRegister [filterId].FR1 = (mask1_reg << 16) | id1_reg;
|
||||
CAN->sFilterRegister [filterId].FR2 = (mask2_reg << 16) | id2_reg;
|
||||
|
||||
// assign FIFO
|
||||
if (assignedFIFO == canFIFO_0)
|
||||
CAN->FFA1R &= ~filterBitMask;
|
||||
else
|
||||
CAN->FFA1R |= filterBitMask;
|
||||
|
||||
CAN->FMR &= ~CAN_FMR_FINIT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// can map both STD and EXTENDED IDs
|
||||
u8 can_config_filter_mask_mode_32bit (u8 filterId, canFIFO assignedFIFO, canIdExtension extendedId, canDataRemote dataRemote, u32 id, u32 mask) {
|
||||
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return 0;
|
||||
|
||||
u32 filterBitMask = (u32)(1 << filterId);
|
||||
|
||||
// deactivate filter
|
||||
CAN->FA1R &= ~filterBitMask;
|
||||
// enter filter configuration mode
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
// set mask mode
|
||||
CAN->FM1R &= ~ filterBitMask;
|
||||
// set scale mode to 32 bit
|
||||
CAN->FS1R |= filterBitMask;
|
||||
|
||||
if (extendedId == canSTD_ID) {
|
||||
CAN->sFilterRegister [filterId].FR1 = ((u32)id << 21);
|
||||
CAN->sFilterRegister [filterId].FR2 = ((u32)mask << 21);
|
||||
}
|
||||
else {
|
||||
CAN->sFilterRegister [filterId].FR1 = ((u32)id << 3) | (1 << 2);
|
||||
CAN->sFilterRegister [filterId].FR2 = ((u32)mask << 3) | (1 << 2);
|
||||
|
||||
if (dataRemote == canREMOTE_FRAME) {
|
||||
CAN->sFilterRegister [filterId].FR1 |= (1<<1);
|
||||
CAN->sFilterRegister [filterId].FR2 |= (1<<1);
|
||||
}
|
||||
}
|
||||
|
||||
// assign FIFO
|
||||
if (assignedFIFO == canFIFO_0)
|
||||
CAN->FFA1R &= ~filterBitMask;
|
||||
else
|
||||
CAN->FFA1R |= filterBitMask;
|
||||
|
||||
CAN->FMR &= ~CAN_FMR_FINIT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u8 can_config_filter_list_mode_16bit (u8 filterId, canFIFO assignedFIFO, canDataRemote dataRemote, u16 id1, u16 id2, u16 id3, u16 id4) {
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return 0;
|
||||
|
||||
u32 filterBitMask = (u32)(1 << filterId);
|
||||
|
||||
CAN->FA1R &= ~filterBitMask; // deactivate filter
|
||||
CAN->FMR |= CAN_FMR_FINIT; // enter filter configuration mode
|
||||
|
||||
CAN->FM1R |= filterBitMask; // set list mode
|
||||
CAN->FS1R &= ~ filterBitMask; // set scale mode to 16 bit
|
||||
|
||||
|
||||
u32 id1_reg = ((u32)id1 << 5);
|
||||
u32 id2_reg = ((u32)id2 << 5);
|
||||
u32 id3_reg = ((u32)id3 << 5);
|
||||
u32 id4_reg = ((u32)id4 << 5);
|
||||
if (dataRemote == canREMOTE_FRAME) {
|
||||
id1_reg |= (1 << 4);
|
||||
id2_reg |= (1 << 4);
|
||||
id3_reg |= (1 << 4);
|
||||
id4_reg |= (1 << 4);
|
||||
}
|
||||
|
||||
CAN->sFilterRegister [filterId].FR1 = (id1_reg << 16) | id2_reg;
|
||||
CAN->sFilterRegister [filterId].FR2 = (id3_reg << 16) | id4_reg;
|
||||
|
||||
// assign FIFO
|
||||
if (assignedFIFO == canFIFO_0)
|
||||
CAN->FFA1R &= ~filterBitMask;
|
||||
else
|
||||
CAN->FFA1R |= filterBitMask;
|
||||
|
||||
CAN->FMR &= ~CAN_FMR_FINIT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
u8 can_config_filter_list_mode_32bit (u8 filterId, canFIFO assignedFIFO, canIdExtension extendedId, canDataRemote dataRemote, u32 id1, u32 id2) {
|
||||
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return 0;
|
||||
|
||||
u32 filterBitMask = (u32)(1 << filterId);
|
||||
|
||||
CAN->FA1R &= ~filterBitMask; // deactivate filter
|
||||
CAN->FMR |= CAN_FMR_FINIT; // enter filter configuration mode
|
||||
|
||||
CAN->FM1R |= filterBitMask; // set list mode
|
||||
CAN->FS1R |= filterBitMask; // set scale mode to 32 bit
|
||||
|
||||
if (extendedId == canSTD_ID) {
|
||||
CAN->sFilterRegister [filterId].FR1 = (id1 << 21);
|
||||
CAN->sFilterRegister [filterId].FR2 = (id2 << 21);
|
||||
}
|
||||
else {
|
||||
CAN->sFilterRegister [filterId].FR1 = (id1 << 3) | (1 << 2);
|
||||
CAN->sFilterRegister [filterId].FR2 = (id2 << 3) | (1 << 2);
|
||||
|
||||
if (dataRemote == canREMOTE_FRAME) {
|
||||
CAN->sFilterRegister [filterId].FR1 |= (1<<1);
|
||||
CAN->sFilterRegister [filterId].FR2 |= (1<<1);
|
||||
}
|
||||
}
|
||||
|
||||
// assign FIFO
|
||||
if (assignedFIFO == canFIFO_0)
|
||||
CAN->FFA1R &= ~filterBitMask;
|
||||
else
|
||||
CAN->FFA1R |= filterBitMask;
|
||||
|
||||
CAN->FMR &= ~CAN_FMR_FINIT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void can_enable_filter (u8 filterId) {
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return;
|
||||
CAN->FA1R |= (u32)(1<<filterId);
|
||||
}
|
||||
void can_disable_filter (u8 filterId) {
|
||||
|
||||
if (filterId >= N_FILTERS)
|
||||
return;
|
||||
CAN->FA1R &= ~ (u32)(1<<filterId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i8 can_transmit (u16 ID, u8 * data, u8 len, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override) {
|
||||
|
||||
if (idType != canSTD_ID && idType != canEXTENDED_ID)
|
||||
return -1;
|
||||
if (dataRemote != canDATA_FRAME && dataRemote != canREMOTE_FRAME)
|
||||
return -1;
|
||||
if (len > 8 || len == 0)
|
||||
return -1;
|
||||
|
||||
|
||||
// check if the mailbox addressed by
|
||||
u8 mbxCode = (CAN->TSR & (CAN_TSR_CODE_Msk)) >> CAN_TSR_CODE_Pos;
|
||||
|
||||
// check if at least one mailbox is free. In this case, its id is the one
|
||||
// previously read from CAN_TSR <CODE>
|
||||
if ((CAN->TSR & (CAN_TSR_TME0_Msk | CAN_TSR_TME1_Msk | CAN_TSR_TME2_Msk)) != 0) {
|
||||
|
||||
s_mailbox_transmit (mbxCode, ID, data, len, idType, dataRemote);
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
|
||||
// in case none of the mailbox is free, if OVERRIDE LOW PRIO flag was set, look
|
||||
// for the mailbox with the message of lowest priority, abort its transmission
|
||||
// and request the transmission of the new message. The mailbox code with lowest
|
||||
// priority is the one read from CAN_TSR <CODE>
|
||||
else if (override == CAN_OVERRIDE_LOW_PRIO) {
|
||||
|
||||
if (s_abort_mailbox_transmit (mbxCode) && s_mailbox_transmit ((mbxCode-1), ID, data, len, idType, dataRemote)) {
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
else if (override == CAN_OVERRIDE_IF_HIGHER_PRIO) {
|
||||
|
||||
// get lowest priority mailbox message ID type (STD or extended)
|
||||
u8 mbxIdType = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_IDE_Msk) >> CAN_TI0R_IDE_Pos;
|
||||
|
||||
// make sure the two messages have the same ID type (STD or extended)
|
||||
if (mbxIdType == idType) {
|
||||
|
||||
// standard address case
|
||||
if (mbxIdType == 0) {
|
||||
u16 stdId = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_STID_Msk) >> CAN_TI0R_STID_Pos;
|
||||
|
||||
// in case the message for which transmission was requested has higher priority,
|
||||
// abort transmission of the previous and request transmission of the current one
|
||||
if (ID < stdId) {
|
||||
if (s_abort_mailbox_transmit (mbxCode) &&
|
||||
s_mailbox_transmit (mbxCode-1, ID, data, len, idType, dataRemote)) {
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// extended address
|
||||
else {
|
||||
u32 extID = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_EXID_Msk) >> CAN_TI0R_EXID_Pos;
|
||||
if (ID < extID) {
|
||||
if (s_abort_mailbox_transmit (mbxCode) &&
|
||||
s_mailbox_transmit (mbxCode-1, ID, data, len, idType, dataRemote)) {
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
else if (override == CAN_OVERRIDE_ID) {
|
||||
|
||||
// look for the given ID in the transmit mailboxes
|
||||
|
||||
for (u8 mbx=0; mbx <3; mbx++) {
|
||||
|
||||
u8 mbxExtId = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_IDE_Msk) >> CAN_TI0R_IDE_Pos;
|
||||
|
||||
if (mbxExtId == idType) {
|
||||
|
||||
if (mbxExtId) {
|
||||
u32 extId = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_EXID_Msk) >> CAN_TI0R_EXID_Pos;
|
||||
if (extId == ID) {
|
||||
if (s_abort_mailbox_transmit (mbxCode) &&
|
||||
s_mailbox_transmit (mbxCode-1, ID, data, len, idType, dataRemote)) {
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
u16 stdId = (CAN->sTxMailBox [mbxCode].TIR & CAN_TI0R_STID_Msk) >> CAN_TI0R_STID_Pos;
|
||||
if (stdId == ID) {
|
||||
if (s_abort_mailbox_transmit (mbxCode) &&
|
||||
s_mailbox_transmit (mbxCode-1, ID, data, len, idType, dataRemote)) {
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if none of the previous transmits were successful, append the message to the FIFO
|
||||
|
||||
// disable CAN interrupt so that ISR cannot change FIFO content while updating here
|
||||
// NOTE: it is important disable all CAN interrupt since inside ISR the flag for TX
|
||||
// complete is always checked, even if the actual source if the interrupt was another
|
||||
// flag.
|
||||
NVIC_DisableIRQ(CEC_CAN_IRQn);
|
||||
|
||||
|
||||
#ifdef CAN_IMPLEMENT_FIFO
|
||||
if (!FIFO_isFull (&CAN_TxFIFO)) {
|
||||
|
||||
// construct the message
|
||||
canMessage_t message = {
|
||||
.std_ext_id = idType,
|
||||
.data_remote_frame = dataRemote,
|
||||
.id = ID,
|
||||
.data_len = len
|
||||
};
|
||||
memcpy (message.data, data, len);
|
||||
FIFO_Append (&CAN_TxFIFO, (u8*)&message);
|
||||
NVIC_EnableIRQ(CEC_CAN_IRQn);
|
||||
return CAN_TX_OK;
|
||||
}
|
||||
else {
|
||||
NVIC_EnableIRQ(CEC_CAN_IRQn);
|
||||
CAN_TxOverride ();
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CAN_TX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void can_enable_automatic_retransmission (void) {
|
||||
// write to MCR register can be done outside initialization mode
|
||||
CAN->MCR &= ~CAN_MCR_NART;
|
||||
}
|
||||
|
||||
void can_desable_automatic_retransmission (void) {
|
||||
|
||||
CAN->MCR |= CAN_MCR_NART;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
u8 s_abort_mailbox_transmit (u8 mbx) {
|
||||
|
||||
u32 abortMAsk = 0;
|
||||
u32 testMask = 0;
|
||||
|
||||
switch (mbx) {
|
||||
case 1:
|
||||
abortMAsk = CAN_TSR_ABRQ0_Msk;
|
||||
testMask = CAN_TSR_TME0_Msk;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
abortMAsk = CAN_TSR_ABRQ1_Msk;
|
||||
testMask = CAN_TSR_TME1_Msk;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
abortMAsk = CAN_TSR_ABRQ2_Msk;
|
||||
testMask = CAN_TSR_TME2_Msk;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAN->TSR |= abortMAsk;
|
||||
|
||||
u32 startTick = flib_GetTick ();
|
||||
while ((CAN->TSR & testMask) == 0) {
|
||||
if((flib_GetTick() - startTick) > 10)
|
||||
return 0; // flag error
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
u8 s_mailbox_transmit (u8 mbx, u16 ID, u8 * data, u8 len, canIdExtension idType, canDataRemote dataRemote) {
|
||||
|
||||
// make sure the mailbox is actually free
|
||||
if (mbx >= 3 || (CAN->TSR & (CAN_TSR_TME0_Msk << mbx)) == 0)
|
||||
return 0;
|
||||
|
||||
CAN->sTxMailBox[mbx].TIR = ID << (idType == canSTD_ID ? CAN_TI0R_STID_Pos : CAN_TI0R_EXID_Pos);
|
||||
if (idType == canEXTENDED_ID)
|
||||
CAN->sTxMailBox[mbx].TIR |= CAN_TI0R_IDE_Msk;
|
||||
if (dataRemote == canREMOTE_FRAME)
|
||||
CAN->sTxMailBox[mbx].TIR |= CAN_TI0R_RTR_Msk;
|
||||
|
||||
// set data length register
|
||||
CAN->sTxMailBox[mbx].TDTR = (len & 0x0f);
|
||||
|
||||
// reset data registers
|
||||
CAN->sTxMailBox[mbx].TDLR = 0x0000;
|
||||
CAN->sTxMailBox[mbx].TDHR = 0x0000;
|
||||
|
||||
CAN->sTxMailBox[mbx].TDLR |= data[0];
|
||||
if (len > 1)
|
||||
CAN->sTxMailBox[mbx].TDLR |= (data[1] << 8);
|
||||
if (len > 2)
|
||||
CAN->sTxMailBox[mbx].TDLR |= (data[2] << 16);
|
||||
if (len > 3)
|
||||
CAN->sTxMailBox[mbx].TDLR |= (data[3] << 24);
|
||||
if (len > 4)
|
||||
CAN->sTxMailBox[mbx].TDHR |= data[4];
|
||||
if (len > 5)
|
||||
CAN->sTxMailBox[mbx].TDHR |= (data[5] << 8);
|
||||
if (len > 6)
|
||||
CAN->sTxMailBox[mbx].TDHR |= (data[6] << 16);
|
||||
if (len > 7)
|
||||
CAN->sTxMailBox[mbx].TDHR |= (data[7] << 24);
|
||||
|
||||
// request transmission
|
||||
CAN->sTxMailBox[mbx].TIR |= CAN_TI0R_TXRQ_Msk;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
133
can.h
Normal file
133
can.h
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef CAN_h
|
||||
#define CAN_h
|
||||
|
||||
|
||||
#include "ftypes.h"
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
// ========================= CAN Configuration ======================= //
|
||||
|
||||
#define CAN_PRESCALER 2 // f_osc = 24MHz, f_periph = 12MHz
|
||||
#define CAN_SEG1 6
|
||||
#define CAN_SEG2 5
|
||||
#define CAN_SJW 3
|
||||
|
||||
|
||||
|
||||
#define CAN_INIT_ERROR -1
|
||||
#define CAN_INIT_OK 0
|
||||
#define CAN_TX_ERROR -1
|
||||
#define CAN_TX_OK 0
|
||||
|
||||
#define N_FILTERS 14
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
canSTD_ID,
|
||||
canEXTENDED_ID
|
||||
}canIdExtension;
|
||||
|
||||
typedef enum {
|
||||
canDATA_FRAME,
|
||||
canREMOTE_FRAME
|
||||
}canDataRemote;
|
||||
|
||||
|
||||
typedef enum {
|
||||
canFIFO_0,
|
||||
canFIFO_1
|
||||
}canFIFO;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
canIdExtension std_ext_id;
|
||||
canDataRemote data_remote_frame;
|
||||
u32 id;
|
||||
u8 data [8];
|
||||
u8 data_len;
|
||||
|
||||
}canMessage_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
u8 TEC;
|
||||
u8 REC;
|
||||
u8 LEC: 3;
|
||||
u8 error_warning:1;
|
||||
u8 error_passive:1;
|
||||
u8 bus_off:1;
|
||||
|
||||
}canNetworkStatus_t;
|
||||
|
||||
|
||||
/* This enum is used for specifying the behavior of the software
|
||||
* during transmission, when all the mailboxes are full. Either
|
||||
* the message is ignored, the mailbox with lowest priority is
|
||||
* overwritten or if a mailbox has same id is overwritten so
|
||||
* that the most recent data is transmitted
|
||||
* */
|
||||
typedef enum {
|
||||
CAN_DO_NOT_OVERRIDE = 0,
|
||||
CAN_OVERRIDE_LOW_PRIO,
|
||||
CAN_OVERRIDE_IF_HIGHER_PRIO,
|
||||
CAN_OVERRIDE_ID
|
||||
}canTxOverrideBehaviorE;
|
||||
|
||||
|
||||
|
||||
|
||||
i8 can_transmit_f32 (u16 ID, f32 data, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override);
|
||||
i8 can_transmit_u32 (u16 ID, u32 data, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override);
|
||||
|
||||
f32 can_extract_f32 (u8 *payload);
|
||||
u32 can_extract_u32 (u8 *payload);
|
||||
|
||||
|
||||
|
||||
i8 can_init (void);
|
||||
void can_init_minimal (void);
|
||||
i8 can_transmit (u16 ID, u8 * data, u8 len, canIdExtension idType, canDataRemote dataRemote, canTxOverrideBehaviorE override);
|
||||
void can_enable_retransmission (void);
|
||||
void can_disable_retransmission (void);
|
||||
|
||||
|
||||
|
||||
// with 16bit registers only STD IDs can be mapped
|
||||
u8 can_config_filter_mask_mode_16bit (u8 filter_id, canFIFO assigned_fifo, canDataRemote dataRemote, u16 id1, u16 id2, u16 mask1, u16 mask2);
|
||||
u8 can_config_filter_mask_mode_32bit (u8 filter_id, canFIFO assigned_fifo, canIdExtension extendedId, canDataRemote dataRemote, u32 id, u32 mask);
|
||||
u8 can_config_filter_list_mode_16bit (u8 filter_id, canFIFO assigned_fifo, canDataRemote dataRemote, u16 id1, u16 id2, u16 id3, u16 id4);
|
||||
u8 can_config_filter_list_mode_32bit (u8 filter_id, canFIFO assigned_fifo, canIdExtension extendedId, canDataRemote dataRemote, u32 id1, u32 id2);
|
||||
|
||||
void can_enable_filter (u8 filter_id);
|
||||
void can_disable_filter (u8 filter_id);
|
||||
|
||||
canNetworkStatus_t can_get_network_status ();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
30
crc.c
Normal file
30
crc.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* crc.c
|
||||
*
|
||||
* Created on: Apr 17, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
void crc_reset (void) {
|
||||
|
||||
CRC->CR |= CRC_CR_RESET;
|
||||
}
|
||||
|
||||
|
||||
u32 crc_compute (u32* start_address, u32* end_address) {
|
||||
|
||||
for (; start_address < end_address; start_address++) {
|
||||
CRC->DR = *start_address;
|
||||
}
|
||||
return CRC->DR;
|
||||
}
|
||||
|
||||
|
||||
u32 crc_get (void) {
|
||||
return CRC->DR;
|
||||
}
|
88
flash.c
Normal file
88
flash.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* flash.c
|
||||
*
|
||||
* Created on: Apr 12, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#include "flash.h"
|
||||
#include "ftypes.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void flash_unlock (void) {
|
||||
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) != 0) {
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
}
|
||||
|
||||
void flash_lock (void) {
|
||||
FLASH->CR |= FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void flash_erase_page (u32 page) {
|
||||
// make sure no operation is ongoing
|
||||
flash_wait_last_op();
|
||||
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
FLASH->AR = page;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
|
||||
flash_wait_last_op ();
|
||||
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
}
|
||||
|
||||
|
||||
// write data in LITTLE ENDIAN format
|
||||
u8 flash_program_word (u32 address, u32 data) {
|
||||
|
||||
flash_program_hword (address, (u16)data);
|
||||
flash_program_hword (address +2, (u16)(data>>16));
|
||||
|
||||
u32 read_data = *(volatile u32*) (address);
|
||||
return (read_data == data);
|
||||
}
|
||||
|
||||
u8 flash_program_hword (u32 address, u16 data) {
|
||||
|
||||
flash_wait_last_op ();
|
||||
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
|
||||
// write the byte into FLASH as if it was with a normal memory address
|
||||
*(volatile u16*) (address) = data;
|
||||
|
||||
flash_wait_last_op ();
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
|
||||
|
||||
u16 read_data = *(volatile u16*) (address);
|
||||
return (read_data == data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void flash_wait_last_op () {
|
||||
// wait for operation to complete
|
||||
while((FLASH->SR & FLASH_SR_BSY) != 0);
|
||||
|
||||
// clear end of operation flag if it was set
|
||||
if ((FLASH->SR & FLASH_SR_EOP) != 0)
|
||||
FLASH->SR |= FLASH_SR_EOP;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
67
flash.h
Normal file
67
flash.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* flash.h
|
||||
*
|
||||
* Created on: Apr 12, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#ifndef FLASH_H_
|
||||
#define FLASH_H_
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define FLASH_PSIZE_BYTE 0x00000000U
|
||||
#define FLASH_PSIZE_HALF_WORD 0x00000100U
|
||||
#define FLASH_PSIZE_WORD 0x00000200U
|
||||
#define FLASH_PSIZE_DOUBLE_WORD 0x00000300U
|
||||
#define CR_PSIZE_MASK 0xFFFFFCFFU
|
||||
|
||||
#define FLASH_VOLTAGE_RANGE_1 0x00000000U /*!< Device operating range: 1.8V to 2.1V */
|
||||
#define FLASH_VOLTAGE_RANGE_2 0x00000001U /*!< Device operating range: 2.1V to 2.7V */
|
||||
#define FLASH_VOLTAGE_RANGE_3 0x00000002U /*!< Device operating range: 2.7V to 3.6V */
|
||||
#define FLASH_VOLTAGE_RANGE_4 0x00000003U /*!< Device operating range: 2.7V to 3.6V + External Vpp */
|
||||
|
||||
#define FLASH_SECTOR_0 0U /*!< Sector Number 0 */
|
||||
#define FLASH_SECTOR_1 1U /*!< Sector Number 1 */
|
||||
#define FLASH_SECTOR_2 2U /*!< Sector Number 2 */
|
||||
#define FLASH_SECTOR_3 3U /*!< Sector Number 3 */
|
||||
#define FLASH_SECTOR_4 4U /*!< Sector Number 4 */
|
||||
#define FLASH_SECTOR_5 5U /*!< Sector Number 5 */
|
||||
#define FLASH_SECTOR_6 6U /*!< Sector Number 6 */
|
||||
#define FLASH_SECTOR_7 7U /*!< Sector Number 7 */
|
||||
|
||||
#define FLASH_SECTOR_TOTAL 8U
|
||||
|
||||
#define FLASH_TIMEOUT_VALUE 50000U /* 50 s */
|
||||
|
||||
|
||||
|
||||
|
||||
#define flash_is_locked() ((FLASH->CR & FLASH_CR_LOCK) != 0)
|
||||
|
||||
|
||||
void flash_unlock (void);
|
||||
void flash_lock (void);
|
||||
|
||||
void flash_wait_last_op();
|
||||
|
||||
void flash_erase_page (u32 page);
|
||||
u8 flash_program_word (u32 address, u32 data);
|
||||
u8 flash_program_hword (u32 address, u16 data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FLASH_H_ */
|
198
gpio.h
Normal file
198
gpio.h
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* gpio.h
|
||||
*
|
||||
* Created on: Mar 6, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#ifndef GPIO_h
|
||||
#define GPIO_h
|
||||
|
||||
#include "stm32f042x6.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* GPIO DEFINES
|
||||
*========================================================================================*/
|
||||
|
||||
typedef enum {
|
||||
|
||||
GPIO_AF_TIM3 = 0x01,
|
||||
GPIO_AF_TIM2 = 0x02,
|
||||
}GPIO_AF_enum;
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
GPIO_OSPEED_LOW = 0,
|
||||
GPIO_OSPEED_MEDIUM = 1,
|
||||
GPIO_OSPEED_HIGH = 3
|
||||
}GPIO_OSPEED_enum;
|
||||
|
||||
|
||||
|
||||
#define GPIO_OUTPUT_TYPE_Pos 4U
|
||||
#define GPIO_OUTPUT_PP (0x0UL << GPIO_OUTPUT_TYPE_Pos)
|
||||
#define GPIO_OUTPUT_OD (0x1UL << GPIO_OUTPUT_TYPE_Pos)
|
||||
|
||||
#define GPIO_PULL_Mask (0x00000003U)
|
||||
#define GPIO_PULLUP (0x00000001U)
|
||||
#define GPIO_PULLDOWN (0x00000002U)
|
||||
|
||||
#define GPIO_AF_Mask (0x0000000fU)
|
||||
#define GPIO_AF_Wdth (4U)
|
||||
#define GPIO_AF0_USART1 ((uint8_t)0x00U)
|
||||
|
||||
|
||||
|
||||
/* ============ OUTPUT LEVEL SET =========== */
|
||||
#define GPIO_SET(pin) PRVT_GPIO_SET (pin##_port, pin##_npin)
|
||||
#define GPIO_CLR(pin) PRVT_GPIO_CLR (pin##_port, pin##_npin)
|
||||
#define GPIO_TOGGLE(pin) PRVT_GPIO_TOGGLE (pin##_port, pin##_npin)
|
||||
|
||||
|
||||
#define GPIO_SET_OSPEED(pin, speed) PRVT_GPIO_SET_OSPEED(pin##_port, pin##npin, speed)
|
||||
|
||||
/* ============ ALTERNATE FUNCTION SET =========== */
|
||||
#define GPIO_SET_MODE_ALTERNATE(pin) PRVT_GPIO_SET_ALT(pin##_port, pin##npin)
|
||||
|
||||
#define GPIO_SET_AFRL(pin, af) PRVT_GPIO_SET_AFRL(pin##_port, pin##_npin, af)
|
||||
#define GPIO_SET_AFRH(pin, af) PRVT_GPIO_SET_AFRH(pin##_port, pin##_npin, af)
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* GPIO CONTROL MACROS
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
#define GPIO_INPUT_GET_VALUE(pin) PRVT_GPIO_INPUT_GET_VALUE(pin##_port, pin##_npin)
|
||||
|
||||
|
||||
#define GPIO_AF_PP(pin) \
|
||||
PRVT_GPIO_SET_ALT(pin##_port, pin##_npin); \
|
||||
PRVT_GPIO_SET_OSPEED (pin##_port, pin##_npin, GPIO_OSPEED_HIGH); \
|
||||
GPIO_SET_OUTPUT_TYPE (pin##_port, pin##_npin, GPIO_OUTPUT_PP); \
|
||||
GPIO_DISABLE_PULL (pin##_port, pin##_npin)
|
||||
|
||||
|
||||
|
||||
#define GPIO_OUTPUT_PP_HS(pin) \
|
||||
GPIO_SET_OUTPUT (pin##_port, pin##_npin); \
|
||||
PRVT_GPIO_SET_OSPEED (pin##_port, pin##_npin, GPIO_OSPEED_HIGH); \
|
||||
GPIO_SET_OUTPUT_TYPE (pin##_port, pin##_npin, GPIO_OUTPUT_PP); \
|
||||
GPIO_DISABLE_PULL (pin##_port, pin##_npin)
|
||||
|
||||
|
||||
#define GPIO_OUTPUT_PP_LS(pin) \
|
||||
GPIO_SET_OUTPUT (pin##_port, pin##_npin); \
|
||||
PRVT_GPIO_SET_OSPEED (pin##_port, pin##_npin, GPIO_OSPEED_LOW); \
|
||||
GPIO_SET_OUTPUT_TYPE (pin##_port, pin##_npin, GPIO_OUTPUT_PP); \
|
||||
GPIO_DISABLE_PULL (pin##_port, pin##_npin)
|
||||
|
||||
|
||||
#define GPIO_INPUT_NOPULL(pin) \
|
||||
GPIO_SET_INPUT(pin##_port, pin##_npin) \
|
||||
GPIO_DISABLE_PULL(pin##_port, pin##_npin)
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* GPIO PRIVATE MACROS: DO NOT USE!
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
#define PRVT_GPIO_SET(port, npin) port->BSRR |= (0x1 << npin)
|
||||
#define PRVT_GPIO_CLR(port, npin) port->BSRR |= (0x1 << (16+npin))
|
||||
#define PRVT_GPIO_TOGGLE(port, npin) port->ODR ^= (0x1 << (npin))
|
||||
|
||||
#define PRVT_GPIO_SET_ALT(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->MODER; \
|
||||
temp &= ~(0b11U << pin*2); \
|
||||
temp |= (0b10 << pin*2); \
|
||||
port->MODER = temp; \
|
||||
}
|
||||
|
||||
#define GPIO_SET_INPUT(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->MODER; \
|
||||
temp &= ~(0b11U << pin*2); \
|
||||
port->MODER = temp; \
|
||||
}
|
||||
|
||||
#define GPIO_SET_OUTPUT(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->MODER; \
|
||||
temp &= ~(0b11U << pin*2); \
|
||||
temp |= (0b01 << pin*2); \
|
||||
port->MODER = temp; \
|
||||
}
|
||||
|
||||
|
||||
#define PRVT_GPIO_SET_OSPEED(port, pin, speed) \
|
||||
{ \
|
||||
u32 temp = port->OSPEEDR; \
|
||||
temp &= ~(0b11U << pin*2); \
|
||||
temp |= (speed << pin*2); \
|
||||
port->OSPEEDR = temp; \
|
||||
}
|
||||
|
||||
|
||||
#define GPIO_SET_OUTPUT_TYPE(port, pin, type) \
|
||||
{ \
|
||||
u32 temp = port->OTYPER; \
|
||||
temp &= ~(0b01U << pin); \
|
||||
temp |= (type << pin); \
|
||||
port->OTYPER = temp; \
|
||||
}
|
||||
|
||||
#define GPIO_DISABLE_PULL(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->PUPDR; \
|
||||
temp &= ~(GPIO_PULL_Mask << pin*2); \
|
||||
port->PUPDR = temp; \
|
||||
}
|
||||
|
||||
#define GPIO_ENABLE_PULLUP(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->PUPDR; \
|
||||
temp &= ~(GPIO_PULL_Mask << pin*2); \
|
||||
temp |= (GPIO_PULLUP << pin*2); \
|
||||
port->PUPDR = temp; \
|
||||
}
|
||||
|
||||
#define GPIO_ENABLE_PULLDOWN(port, pin) \
|
||||
{ \
|
||||
u32 temp = port->PUPDR; \
|
||||
temp &= ~(GPIO_PULL_Mask << pin*2); \
|
||||
temp |= (GPIO_PULLDOWN << pin*2); \
|
||||
port->PUPDR = temp; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define PRVT_GPIO_SET_AFRL(port, pin, af) \
|
||||
{ \
|
||||
u32 temp = port->AFR[0]; \
|
||||
temp &= ~(GPIO_AF_Mask << pin*GPIO_AF_Wdth); \
|
||||
temp |= (af << pin*GPIO_AF_Wdth); \
|
||||
port->AFR[0] = temp; \
|
||||
}
|
||||
|
||||
|
||||
#define PRVT_GPIO_SET_AFRH(port, pin, af) \
|
||||
{ \
|
||||
u32 temp = port->AFR[1]; \
|
||||
temp &= ~(GPIO_AF_Mask << (pin-8)*GPIO_AF_Wdth); \
|
||||
temp |= (af << (pin-8)*GPIO_AF_Wdth); \
|
||||
port->AFR[1] = temp; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GPIO_h */
|
154
mcu.c
Normal file
154
mcu.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* mcu.c
|
||||
*
|
||||
* Created on: Feb 29, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
|
||||
#include "mcu.h"
|
||||
#include "ftypes.h"
|
||||
|
||||
|
||||
|
||||
|
||||
sysclk_src get_sysclk_src (void) {
|
||||
|
||||
return ((RCC->CFGR & RCC_CFGR_SWS_Msk) >> RCC_CFGR_SWS_Pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void backup_clock_init (void) {
|
||||
|
||||
// disable PLL
|
||||
RCC->CR &= ~RCC_CR_PLLON;
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) != 0); // wait until PLL is unlocked
|
||||
|
||||
RCC->CFGR2 = PLL_PREDIV_BACKUP;
|
||||
|
||||
RCC->CFGR = (CLK_PLLMUL_BACKUP << RCC_CFGR_PLLMUL_Pos) |
|
||||
(PLL_SRC_BACKUP << RCC_CFGR_PLLSRC_Pos) |
|
||||
(APB_SRC << RCC_CFGR_PPRE_Pos) |
|
||||
(AHB_SRC << RCC_CFGR_HPRE_Pos);
|
||||
|
||||
|
||||
RCC->CR |= RCC_CR_PLLON | (CSS_STATUS << RCC_CR_CSSON_Pos); // enable PLL
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // wait until PLL is locked and ready
|
||||
|
||||
|
||||
RCC->CFGR |= (SYSCLK_SRC << RCC_CFGR_SW_Pos);
|
||||
}
|
||||
|
||||
void clock_init (void) {
|
||||
|
||||
|
||||
// disable PLL
|
||||
RCC->CR &= ~RCC_CR_PLLON;
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) != 0); // wait until PLL is unlocked
|
||||
|
||||
RCC->CR |= (HSE_STATUS << RCC_CR_HSEON_Pos);
|
||||
|
||||
RCC->CFGR2 = PLL_PREDIV;
|
||||
|
||||
RCC->CFGR = (CLK_PLLMUL << RCC_CFGR_PLLMUL_Pos) |
|
||||
(PLL_SRC << RCC_CFGR_PLLSRC_Pos) |
|
||||
(APB_SRC << RCC_CFGR_PPRE_Pos) |
|
||||
(AHB_SRC << RCC_CFGR_HPRE_Pos);
|
||||
|
||||
|
||||
RCC->CR |= RCC_CR_PLLON | (CSS_STATUS << RCC_CR_CSSON_Pos); // enable PLL
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // wait until PLL is locked and ready
|
||||
|
||||
|
||||
RCC->CFGR |= (SYSCLK_SRC << RCC_CFGR_SW_Pos);
|
||||
}
|
||||
|
||||
|
||||
// init clock in this function
|
||||
void SystemInit (void) {
|
||||
|
||||
clock_init ();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
volatile systemClockTreeT systemClockTree;
|
||||
u32 SystemCoreClock;
|
||||
const u16 AHBPrescTable[16] = {1,1,1,1,1,1,1,1,2,4,8,16,64,128,256,512};
|
||||
const u8 APBPrescTable[8] = {1,1,1,1,2,4,8,16};
|
||||
|
||||
|
||||
|
||||
|
||||
#define HSE_FCLK 8000000U
|
||||
#define HSI_FCLK 8000000U
|
||||
#define HSI48_FCLK 48000000
|
||||
|
||||
|
||||
|
||||
void SystemCoreClockUpdate (void) {
|
||||
|
||||
sysclk_src sysclkSrc = (RCC->CFGR & RCC_CFGR_SW_Msk) >> RCC_CFGR_SW_Pos;
|
||||
|
||||
|
||||
if (sysclkSrc == SYSCLK_SRC_HSI )
|
||||
SystemCoreClock = HSI_FCLK;
|
||||
|
||||
else if (sysclkSrc == SYSCLK_SRC_HSE)
|
||||
SystemCoreClock = HSE_FCLK;
|
||||
|
||||
else if (sysclkSrc == SYSCLK_SRC_HSI48)
|
||||
SystemCoreClock = HSI48_FCLK;
|
||||
|
||||
else if (sysclkSrc == SYSCLK_SRC_PLL) {
|
||||
|
||||
pll_mul pllMul = (RCC->CFGR & RCC_CFGR_PLLMUL_Msk) >> RCC_CFGR_PLLMUL_Pos;
|
||||
pll_src pllSrc = (RCC->CFGR & RCC_CFGR_PLLSRC_Msk) >> RCC_CFGR_PLLSRC_Pos;
|
||||
u16 prediv = ((RCC->CFGR2 & RCC_CFGR2_PREDIV_Msk) >> RCC_CFGR2_PREDIV_Pos) +1;
|
||||
|
||||
switch (pllSrc) {
|
||||
|
||||
case PLL_SRC_HSI_2:
|
||||
SystemCoreClock = HSI_FCLK / 2 * (pllMul+2);
|
||||
break;
|
||||
|
||||
case PLL_SRC_HSI_PREDIV:
|
||||
SystemCoreClock = HSI_FCLK / prediv * (pllMul+2);
|
||||
break;
|
||||
|
||||
case PLL_SRC_HSE_PREDIV:
|
||||
SystemCoreClock = HSE_FCLK / prediv * (pllMul+2);
|
||||
break;
|
||||
|
||||
case PLL_SRC_HSI48_PREDIV:
|
||||
SystemCoreClock = HSI48_FCLK / prediv * (pllMul+2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
systemClockTree.SYS_clk = SystemCoreClock;
|
||||
|
||||
u8 AHB_psc_idx = (RCC->CFGR & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos;
|
||||
u16 AHB_psc = AHBPrescTable [AHB_psc_idx];
|
||||
u8 APB_psc_idx = (RCC->CFGR & RCC_CFGR_PPRE_Msk) >> RCC_CFGR_PPRE_Pos;
|
||||
u16 APB_psc = APBPrescTable [APB_psc_idx];
|
||||
|
||||
systemClockTree.AHB_clk = SystemCoreClock / AHB_psc;
|
||||
systemClockTree.APB_clk = systemClockTree.AHB_clk / APB_psc;
|
||||
|
||||
systemClockTree.TIM_clk = (APB_psc == 1 ? systemClockTree.APB_clk : systemClockTree.APB_clk*2);
|
||||
|
||||
systemClockTree.sysTick_clk = systemClockTree.APB_clk;
|
||||
systemClockTree.USART1_clk = systemClockTree.APB_clk;
|
||||
systemClockTree.USART2_clk = systemClockTree.APB_clk;
|
||||
systemClockTree.USART3_clk = systemClockTree.APB_clk;
|
||||
systemClockTree.ADC_clk = systemClockTree.APB_clk;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
433
mcu.h
Normal file
433
mcu.h
Normal file
@ -0,0 +1,433 @@
|
||||
/* **************************************************************************
|
||||
* @file mcu.h
|
||||
*
|
||||
* @date March 6 2024
|
||||
* @author Francesco Gritti
|
||||
****************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef MCU_h
|
||||
#define MCU_h
|
||||
|
||||
|
||||
#include "ftypes.h"
|
||||
#include "stm32f042x6.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
u32 getTick (void);
|
||||
#define flib_GetTick getTick
|
||||
|
||||
typedef struct {
|
||||
|
||||
u32 SYS_clk;
|
||||
u32 sysTick_clk;
|
||||
u32 APB_clk;
|
||||
u32 AHB_clk;
|
||||
u32 TIM_clk;
|
||||
u32 USART1_clk;
|
||||
u32 USART2_clk;
|
||||
u32 USART3_clk;
|
||||
u32 ADC_clk;
|
||||
|
||||
}systemClockTreeT;
|
||||
|
||||
extern volatile systemClockTreeT systemClockTree;
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* DRIVER CONFIGURATION
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
#include "gpio.h"
|
||||
#include "tim.h"
|
||||
|
||||
#if defined(tim1_timebase)
|
||||
|
||||
void TIM1_init (void);
|
||||
#endif
|
||||
|
||||
#if defined(tim2_pwm)
|
||||
|
||||
void TIM2_pwm_init (void);
|
||||
void TIM2_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM2_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM2_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM2_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
|
||||
#elif defined (tim2_ic) || defined (tim2_adc_timebase)
|
||||
void TIM2_init (void);
|
||||
#endif
|
||||
|
||||
#if defined(tim3_pwm)
|
||||
|
||||
void TIM3_pwm_init (void);
|
||||
void TIM3_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM3_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM3_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
void TIM3_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value);
|
||||
|
||||
#elif defined (tim3_ic)
|
||||
void TIM3_ic_init (void);
|
||||
|
||||
#elif defined (tim3_adc_timebase)
|
||||
void TIM3_init (void);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(tim14_timer)
|
||||
void TIM14_init (void);
|
||||
#endif
|
||||
|
||||
#if defined(use_can)
|
||||
#include "can.h"
|
||||
#endif
|
||||
|
||||
#if defined(use_usart1)
|
||||
#include "usart1.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* CLOCK DEFINITIONS, MACROS AND FUNCTIONS
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
// clock configuration must be specified in "main.h" since it can be
|
||||
// custom for every application
|
||||
void clock_init (void);
|
||||
void backup_clock_init (void);
|
||||
|
||||
typedef enum {
|
||||
PLL_MUL_2 = 0,
|
||||
PLL_MUL_3,
|
||||
PLL_MUL_4,
|
||||
PLL_MUL_5,
|
||||
PLL_MUL_6,
|
||||
PLL_MUL_7,
|
||||
PLL_MUL_8,
|
||||
PLL_MUL_9,
|
||||
PLL_MUL_10,
|
||||
PLL_MUL_11,
|
||||
PLL_MUL_12,
|
||||
PLL_MUL_13,
|
||||
PLL_MUL_14,
|
||||
PLL_MUL_15,
|
||||
PLL_MUL_16,
|
||||
|
||||
}pll_mul;
|
||||
|
||||
typedef enum {
|
||||
SYSCLK_SRC_HSI = 0,
|
||||
SYSCLK_SRC_HSE,
|
||||
SYSCLK_SRC_PLL,
|
||||
SYSCLK_SRC_HSI48,
|
||||
|
||||
}sysclk_src;
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
PLL_SRC_HSI_2 = 0,
|
||||
PLL_SRC_HSI_PREDIV,
|
||||
PLL_SRC_HSE_PREDIV,
|
||||
PLL_SRC_HSI48_PREDIV,
|
||||
|
||||
}pll_src;
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
AHB_SRC_SYSCLK = 0,
|
||||
AHB_SRC_SYSCLK_2 = 8,
|
||||
AHB_SRC_SYSCLK_4,
|
||||
AHB_SRC_SYSCLK_8,
|
||||
AHB_SRC_SYSCLK_16,
|
||||
AHB_SRC_SYSCLK_64,
|
||||
AHB_SRC_SYSCLK_128,
|
||||
AHB_SRC_SYSCLK_256,
|
||||
AHB_SRC_SYSCLK_512,
|
||||
|
||||
}ahb_clk_src;
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
APB_SRC_AHB = 0,
|
||||
APB_SRC_AHB_2 = 4,
|
||||
APB_SRC_AHB_4,
|
||||
APB_SRC_AHB_8,
|
||||
APB_SRC_AHB_16
|
||||
}apb_clk_src;
|
||||
|
||||
|
||||
typedef enum {
|
||||
CSS_DISABLE,
|
||||
CSS_ENABLE
|
||||
}clock_security_system;
|
||||
|
||||
|
||||
|
||||
|
||||
// this macro allows to correctly enable one peripheral's clock.
|
||||
// after setting the relative bit, it reads back the value
|
||||
// effectively delaying two clock cycles (cause of the &
|
||||
// operation. The compiler is prevented from optimizing
|
||||
// this operation away by declaring tmpreg as volatile
|
||||
|
||||
#define ENABLE_CLK(reg, bit) do { \
|
||||
volatile u32 tmpreg; \
|
||||
reg |= bit; \
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = (RCC->APB1ENR & RCC_APB1ENR_CANEN); \
|
||||
(void) tmpreg; \
|
||||
} while(0U)
|
||||
|
||||
|
||||
|
||||
#define FLASH_PREFATCH_ENABLE() FLASH->ACR |= FLASH_ACR_PRFTBE
|
||||
#define SYSCFG_REMAP_PA11_PA12() SYSCFG->CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP
|
||||
#define SYSCFG_REMAP_SRAM() SYSCFG->CFGR1 |= 0b11;
|
||||
#define SYSCFG_REMAP_FLASH() SYSCFG->CFGR1 &= ~0b11;
|
||||
|
||||
|
||||
|
||||
|
||||
#define SYSCFG_DISABLE_REMAP_PA11_PA12() SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_PA11_PA12_RMP
|
||||
|
||||
#define RCC_TIM1_CLK_ENABLE() ENABLE_CLK(RCC->APB2ENR, RCC_APB2ENR_TIM1EN)
|
||||
#define RCC_TIM2_CLK_ENABLE() ENABLE_CLK(RCC->APB1ENR, RCC_APB1ENR_TIM2EN)
|
||||
#define RCC_TIM3_CLK_ENABLE() ENABLE_CLK(RCC->APB1ENR, RCC_APB1ENR_TIM3EN)
|
||||
#define RCC_TIM14_CLK_ENABLE() ENABLE_CLK(RCC->APB1ENR, RCC_APB1ENR_TIM14EN)
|
||||
#define RCC_USART1_CLK_ENABLE() ENABLE_CLK(RCC->APB2ENR, RCC_APB2ENR_USART1EN)
|
||||
|
||||
#define RCC_GPIOA_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIOAEN)
|
||||
#define RCC_GPIOB_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIOBEN)
|
||||
#define RCC_GPIOC_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIOCEN)
|
||||
#define RCC_GPIOD_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIODEN)
|
||||
#define RCC_GPIOE_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIOEEN)
|
||||
#define RCC_GPIOF_CLK_ENABLE() ENABLE_CLK(RCC->AHBENR, RCC_AHBENR_GPIOFEN)
|
||||
|
||||
#define RCC_CAN1_CLK_ENABLE() ENABLE_CLK(RCC->APB1ENR, RCC_APB1ENR_CANEN)
|
||||
|
||||
#define RCC_SYSCFG_CLK_ENABLE() ENABLE_CLK(RCC->APB2ENR, RCC_APB2ENR_SYSCFGCOMPEN)
|
||||
#define RCC_PWR_CLK_ENABLE() ENABLE_CLK(RCC->APB1ENR, RCC_APB1ENR_PWREN)
|
||||
|
||||
#define RCC_DMA_CLK_ENABLE() ENABLE_CLK (RCC->AHBENR, RCC_AHBENR_DMAEN)
|
||||
#define RCC_ADC_CLK_ENABLE() ENABLE_CLK (RCC->APB2ENR, RCC_APB2ENR_ADCEN)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* USART MACROS
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
#define USART_TX_ENABLE(usart) (usart->CR1 |= USART_CR1_TE)
|
||||
#define USART_TX_DISABLE(usart) (usart->CR1 &= ~USART_CR1_TE)
|
||||
|
||||
#define USART_RX_ENABLE(usart) (usart->CR1 |= USART_CR1_RE)
|
||||
#define USART_RX_DISABLE(usart) (usart->CR1 &= ~USART_CR1_RE)
|
||||
|
||||
#define USART_ENABLE(usart) (usart->CR1 |= USART_CR1_UE)
|
||||
#define USART_DISABLE(usart) (usart->CR1 &= ~USART_CR1_UE)
|
||||
|
||||
|
||||
// enable usart, receiver and transmitter
|
||||
#define USART_START(usart) (usart->CR1 |= (USART_CR1_RE | USART_CR1_TE | USART_CR1_UE))
|
||||
#define USART_STOP(usart) (usart->CR1 &= ~(USART_CR1_RE | USART_CR1_TE | USART_CR1_UE))
|
||||
|
||||
|
||||
#define USART_ENABLE_TX_DATA_REGISTER_EMPTY_INT(usart) (usart->CR1 |= USART_CR1_TXEIE)
|
||||
#define USART_DISABLE_TX_DATA_REGISTER_EMPTY_INT(usart) (usart->CR1 &= ~USART_CR1_TXEIE)
|
||||
|
||||
#define USART_ENABLE_DATA_RECEIVED_INT(usart) (usart->CR1 |= USART_CR1_RXNEIE)
|
||||
#define USART_DISABLE_DATA_RECEIVED_INT(usart) (usart->CR1 &= ~USART_CR1_RXNEIE)
|
||||
|
||||
#define USART_SET_TRANSMIT_DATA(usart, data) (usart->TDR = data)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* ADC MACROS
|
||||
*========================================================================================*/
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_CONV_MODE_SINGLE = 0,
|
||||
ADC_CONV_MODE_CONTINUOUS
|
||||
}adc_conv_mode;
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_OVRMOD_PRESERVE = 0,
|
||||
ADC_OVRMOD_OVERWRITE
|
||||
}adc_ovrmod;
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_EXTEN_DISABLED = 0,
|
||||
ADC_EXTEN_RISING_EDGE,
|
||||
ADC_EXTEN_FALLING_EDGE,
|
||||
ADC_EXTEN_BOTH_EDGES
|
||||
}adc_ext_trig_en;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ADC_EXTSEL_TIM1_TRGO = 0,
|
||||
ADC_EXTSEL_TIM1_CC4,
|
||||
ADC_EXTSEL_TIM2_TRGO,
|
||||
ADC_EXTSEL_TIM3_TRGO,
|
||||
ADC_EXTSEL_TIM15_TRGO,
|
||||
}adc_extsel;
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_ALIGN_RIGHT = 0,
|
||||
ADC_ALIGN_LEFT
|
||||
}adc_align;
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_RES_12bit = 0,
|
||||
ADC_RES_10bit,
|
||||
ADC_RES_8bit,
|
||||
ADC_RES_6bit
|
||||
}adc_resolution;
|
||||
|
||||
typedef enum {
|
||||
ADC_DMA_MODE_ONE_SHOT = 0,
|
||||
ADC_DMA_MODE_CIRCULAR
|
||||
}adc_dma_mode;
|
||||
|
||||
typedef enum {
|
||||
ADC_DMA_DISABLED = 0,
|
||||
ADC_DMA_ENABLED
|
||||
}adc_dma_enable;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ADC_CLK_ADCCLK = 0,
|
||||
ADC_CLK_PCLK_2,
|
||||
ADC_CLK_PCLK_4,
|
||||
}adc_clk;
|
||||
|
||||
typedef enum {
|
||||
|
||||
ADC_SAMPLE_TIME_1_5 = 0,
|
||||
ADC_SAMPLE_TIME_7_5,
|
||||
ADC_SAMPLE_TIME_13_5,
|
||||
ADC_SAMPLE_TIME_28_5,
|
||||
ADC_SAMPLE_TIME_41_5,
|
||||
ADC_SAMPLE_TIME_55_5,
|
||||
ADC_SAMPLE_TIME_71_5,
|
||||
ADC_SAMPLE_TIME_239_5,
|
||||
}adc_sample_time;
|
||||
|
||||
|
||||
#define ADC_CHANNEL_0 ( 0x00000000U)
|
||||
#define ADC_CHANNEL_1 ( 0x00000001U)
|
||||
#define ADC_CHANNEL_2 ( 0x00000002U)
|
||||
#define ADC_CHANNEL_3 ( 0x00000003U)
|
||||
#define ADC_CHANNEL_4 ( 0x00000004U)
|
||||
#define ADC_CHANNEL_5 ( 0x00000005U)
|
||||
#define ADC_CHANNEL_6 ( 0x00000006U)
|
||||
#define ADC_CHANNEL_7 ( 0x00000007U)
|
||||
#define ADC_CHANNEL_8 ( 0x00000008U)
|
||||
#define ADC_CHANNEL_9 ( 0x00000009U)
|
||||
#define ADC_CHANNEL_10 ( 0x0000000AU)
|
||||
#define ADC_CHANNEL_11 ( 0x0000000BU)
|
||||
#define ADC_CHANNEL_12 ( 0x0000000CU)
|
||||
#define ADC_CHANNEL_13 ( 0x0000000DU)
|
||||
#define ADC_CHANNEL_14 ( 0x0000000EU)
|
||||
#define ADC_CHANNEL_15 ( 0x0000000FU)
|
||||
#define ADC_CHANNEL_16 ( 0x00000010U)
|
||||
#define ADC_CHANNEL_17 ( 0x00000011U)
|
||||
|
||||
|
||||
|
||||
#if defined(use_adc) || defined(use_adc_dma)
|
||||
|
||||
void ADC_init (void);
|
||||
void ADC_addChannelToScanList (u8 channel);
|
||||
void ADC_removeChannelFromScanList (u8 channel);
|
||||
|
||||
// configure DMA and start conversion
|
||||
void ADC_startConversionDMA (u8 channels, u16 * ADC_array);
|
||||
|
||||
// configure DMA only. Conversion will be triggered lately by software or by hardware
|
||||
// through an event
|
||||
void ADC_configureDMA (u8 channels, u16 * ADC_array);
|
||||
u8 ADC_disable (void);
|
||||
u8 ADC_enable (void);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* DMA MACROS
|
||||
*========================================================================================*/
|
||||
|
||||
typedef enum {
|
||||
|
||||
DMA_MSIZE_8_bit = 0,
|
||||
DMA_MSIZE_16_bit,
|
||||
DMA_MSIZE_32_bit
|
||||
}dma_msize;
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
DMA_PSIZE_8_bit = 0,
|
||||
DMA_PSIZE_16_bit,
|
||||
DMA_PSIZE_32_bit
|
||||
}dma_psize;
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
DMA_PRIO_LOW = 0,
|
||||
DMA_PRIO_MEDIUM,
|
||||
DMA_PRIO_HIGH,
|
||||
DMA_PRIO_VERY_HIGH,
|
||||
}dma_prio;
|
||||
|
||||
|
||||
#define DMA_SET_NDATA(dma_channel, n) dma_channel->NDT = n
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* CRC
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
void crc_reset (void);
|
||||
u32 crc_compute (u32* start_address, u32* end_address);
|
||||
u32 crc_get (void);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* MCU_h */
|
128
tim.h
Normal file
128
tim.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* tim.h
|
||||
*
|
||||
* Created on: Apr 3, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#ifndef TIM_H_
|
||||
#define TIM_H_
|
||||
|
||||
|
||||
|
||||
|
||||
/*========================================================================================*
|
||||
* TIMER MACROS
|
||||
*========================================================================================*/
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
TIM_OC_ACTIVE_HIGH = 0,
|
||||
TIM_OC_ACTIVE_LOW,
|
||||
} TIM_OC_ACTIVE_STATE_enum;
|
||||
|
||||
typedef enum {
|
||||
|
||||
TIM_IC_ACTIVE_RISING,
|
||||
TIM_IC_ACTIVE_FALLING,
|
||||
TIM_IC_ACTIVE_BOTH
|
||||
|
||||
}TIM_IC_ACTIVE_EDGE_enum;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define TIM_PWM_MODE1 0x06 // active when CNT < PERIOD
|
||||
#define TIM_PWM_MODE2 0x07 // inactive when CNT < PERIOD
|
||||
#define TIM_FORCE_ACTIVE 0x05
|
||||
#define TIM_FORCE_INACTIVE 0x04
|
||||
|
||||
|
||||
#define TIM_COUNTER_ENABLE(timer) timer->CR1 |= TIM_CR1_CEN;
|
||||
#define TIM_COUNTER_DISABLE(timer) timer->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
#define TIM_CH1_ENABLE(tim) tim->CCER |= TIM_CCER_CC1E
|
||||
#define TIM_CH2_ENABLE(tim) tim->CCER |= TIM_CCER_CC2E
|
||||
#define TIM_CH3_ENABLE(tim) tim->CCER |= TIM_CCER_CC3E
|
||||
#define TIM_CH4_ENABLE(tim) tim->CCER |= TIM_CCER_CC4E
|
||||
|
||||
#define TIM_CH1_DISABLE(tim) tim->CCER &= ~TIM_CCER_CC1E
|
||||
#define TIM_CH2_DISABLE(tim) tim->CCER &= ~TIM_CCER_CC2E
|
||||
#define TIM_CH3_DISABLE(tim) tim->CCER &= ~TIM_CCER_CC3E
|
||||
#define TIM_CH4_DISABLE(tim) tim->CCER &= ~TIM_CCER_CC4E
|
||||
|
||||
#define TIM_PWM_SET_CH1_POLARITY_ACTIVE_HIGH(tim) tim->CCER &= ~TIM_CCER_CC1P
|
||||
#define TIM_PWM_SET_CH2_POLARITY_ACTIVE_HIGH(tim) tim->CCER &= ~TIM_CCER_CC2P
|
||||
#define TIM_PWM_SET_CH3_POLARITY_ACTIVE_HIGH(tim) tim->CCER &= ~TIM_CCER_CC3P
|
||||
#define TIM_PWM_SET_CH4_POLARITY_ACTIVE_HIGH(tim) tim->CCER &= ~TIM_CCER_CC4P
|
||||
|
||||
#define TIM_PWM_SET_CH1_POLARITY_ACTIVE_LOW(tim) tim->CCER |= TIM_CCER_CC1P
|
||||
#define TIM_PWM_SET_CH2_POLARITY_ACTIVE_LOW(tim) tim->CCER |= TIM_CCER_CC2P
|
||||
#define TIM_PWM_SET_CH3_POLARITY_ACTIVE_LOW(tim) tim->CCER |= TIM_CCER_CC3P
|
||||
#define TIM_PWM_SET_CH4_POLARITY_ACTIVE_LOW(tim) tim->CCER |= TIM_CCER_CC4P
|
||||
|
||||
#define TIM_SET_COUNTER(tim, counter) tim->CNT = counter
|
||||
|
||||
#define TIM_CH1_SET_COMPARE(tim, cmp) tim->CCR1 = cmp
|
||||
#define TIM_CH2_SET_COMPARE(tim, cmp) tim->CCR2 = cmp
|
||||
#define TIM_CH3_SET_COMPARE(tim, cmp) tim->CCR3 = cmp
|
||||
#define TIM_CH4_SET_COMPARE(tim, cmp) tim->CCR4 = cmp
|
||||
|
||||
|
||||
#define TIM_CH1_FORCE_ACTIVE(tim) TIM_CH1_SET_OUTCMP_MODE(tim, TIM_FORCE_ACTIVE)
|
||||
#define TIM_CH2_FORCE_ACTIVE(tim) TIM_CH2_SET_OUTCMP_MODE(tim, TIM_FORCE_ACTIVE)
|
||||
#define TIM_CH3_FORCE_ACTIVE(tim) TIM_CH3_SET_OUTCMP_MODE(tim, TIM_FORCE_ACTIVE)
|
||||
#define TIM_CH4_FORCE_ACTIVE(tim) TIM_CH4_SET_OUTCMP_MODE(tim, TIM_FORCE_ACTIVE)
|
||||
|
||||
#define TIM_CH1_FORCE_INACTIVE(tim) TIM_CH1_SET_OUTCMP_MODE(tim, TIM_FORCE_INACTIVE)
|
||||
#define TIM_CH2_FORCE_INACTIVE(tim) TIM_CH2_SET_OUTCMP_MODE(tim, TIM_FORCE_INACTIVE)
|
||||
#define TIM_CH3_FORCE_INACTIVE(tim) TIM_CH3_SET_OUTCMP_MODE(tim, TIM_FORCE_INACTIVE)
|
||||
#define TIM_CH4_FORCE_INACTIVE(tim) TIM_CH4_SET_OUTCMP_MODE(tim, TIM_FORCE_INACTIVE)
|
||||
|
||||
#define TIM_CH1_PWM(tim, mode) TIM_CH1_SET_OUTCMP_MODE(tim, mode)
|
||||
#define TIM_CH2_PWM(tim, mode) TIM_CH2_SET_OUTCMP_MODE(tim, mode)
|
||||
#define TIM_CH3_PWM(tim, mode) TIM_CH3_SET_OUTCMP_MODE(tim, mode)
|
||||
#define TIM_CH4_PWM(tim, mode) TIM_CH4_SET_OUTCMP_MODE(tim, mode)
|
||||
|
||||
|
||||
|
||||
#define TIM_CH1_SET_OUTCMP_MODE(tim, mode) \
|
||||
{ \
|
||||
u32 temp = tim->CCMR1; \
|
||||
temp &= ~TIM_CCMR1_OC1M_Msk; \
|
||||
temp |= (mode << TIM_CCMR1_OC1M_Pos); \
|
||||
tim->CCMR1 = temp; \
|
||||
}
|
||||
|
||||
|
||||
#define TIM_CH2_SET_OUTCMP_MODE(tim, mode) \
|
||||
{ \
|
||||
u32 temp = tim->CCMR1; \
|
||||
temp &= ~TIM_CCMR1_OC2M_Msk; \
|
||||
temp |= (mode << TIM_CCMR1_OC2M_Pos); \
|
||||
tim->CCMR1 = temp; \
|
||||
}
|
||||
|
||||
#define TIM_CH3_SET_OUTCMP_MODE(tim, mode) \
|
||||
{ \
|
||||
u32 temp = tim->CCMR2; \
|
||||
temp &= ~TIM_CCMR2_OC3M_Msk; \
|
||||
temp |= (mode << TIM_CCMR2_OC3M_Pos); \
|
||||
tim->CCMR2 = temp; \
|
||||
}
|
||||
|
||||
#define TIM_CH4_SET_OUTCMP_MODE(tim, mode) \
|
||||
{ \
|
||||
u32 temp = tim->CCMR2; \
|
||||
temp &= ~TIM_CCMR2_OC4M_Msk; \
|
||||
temp |= (mode << TIM_CCMR2_OC4M_Pos); \
|
||||
tim->CCMR2 = temp; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* TIM_H_ */
|
47
tim1.c
Normal file
47
tim1.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* tim1.c
|
||||
*
|
||||
* Created on: Mar 24, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef tim1_timebase
|
||||
|
||||
|
||||
|
||||
void TIM1_init (void) {
|
||||
|
||||
RCC_TIM1_CLK_ENABLE ();
|
||||
|
||||
TIM1->CR1 = 0x0000;
|
||||
TIM1->DIER |= TIM_DIER_UIE_Msk;
|
||||
TIM1->CNT = 0x0000;
|
||||
TIM1->PSC = 23;
|
||||
TIM1->ARR = 333;
|
||||
|
||||
|
||||
NVIC_SetPriority (TIM1_BRK_UP_TRG_COM_IRQn, 3);
|
||||
NVIC_EnableIRQ (TIM1_BRK_UP_TRG_COM_IRQn);
|
||||
|
||||
// enable timer
|
||||
TIM1->CR1 |= TIM_CR1_CEN_Msk;
|
||||
}
|
||||
|
||||
__attribute__ ((weak)) void tim1_callback (void);
|
||||
|
||||
void TIM1_IRQHandler (void) {
|
||||
|
||||
TIM1->SR &= ~TIM_SR_UIF;
|
||||
tim1_callback ();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
46
tim14.c
Normal file
46
tim14.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* tim14.c
|
||||
*
|
||||
* Created on: Feb 29, 2024
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef tim14_timer
|
||||
|
||||
|
||||
|
||||
void TIM14_init (void) {
|
||||
|
||||
RCC_TIM14_CLK_ENABLE ();
|
||||
|
||||
TIM14->CR1 = 0x0000;
|
||||
TIM14->DIER |= TIM_DIER_UIE_Msk;
|
||||
TIM14->CNT = 0x0000;
|
||||
TIM14->PSC = 24-1;
|
||||
TIM14->ARR = 1000-1;
|
||||
|
||||
|
||||
NVIC_SetPriority (TIM14_IRQn, 3);
|
||||
NVIC_EnableIRQ (TIM14_IRQn);
|
||||
|
||||
// enable timer
|
||||
TIM14->CR1 |= TIM_CR1_CEN_Msk;
|
||||
}
|
||||
|
||||
__attribute__ ((weak)) void tim14_callback (void);
|
||||
|
||||
void TIM14_IRQHandler (void) {
|
||||
|
||||
TIM14->SR &= ~TIM_SR_UIF;
|
||||
tim14_callback ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
194
tim2.c
Normal file
194
tim2.c
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* tim2.c
|
||||
*
|
||||
* Created on: Dec 30, 2023
|
||||
* Author: Francesco Gritti
|
||||
*
|
||||
* This file contains implementation of booth timer 2 input capture and PWM
|
||||
* generation features. only one of the two features can be enabled by
|
||||
* defining the macros "tim2_pwm" or "tim2_ic".
|
||||
*
|
||||
* GPIOs connected to the input/output channels of the timer should be
|
||||
* defined in main.h and they are initialized into the TIM2_init function
|
||||
*/
|
||||
|
||||
|
||||
#include "main.h"
|
||||
#include "mcu.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef tim2_adc_timebase
|
||||
|
||||
|
||||
|
||||
void TIM2_init (void) {
|
||||
|
||||
RCC_TIM2_CLK_ENABLE();
|
||||
|
||||
|
||||
TIM2->CR1 = 0x0000;
|
||||
TIM2->CR2 = (0b010 << TIM_CR2_MMS_Pos);
|
||||
TIM2->DIER = 0x0000; // disable all interrupt requests
|
||||
|
||||
TIM2->PSC = TIM2_PSC;
|
||||
TIM2->ARR = TIM2_PERIOD;
|
||||
|
||||
|
||||
TIM2->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef tim2_pwm
|
||||
|
||||
void TIM2_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM2->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH1_POLARITY_ACTIVE_HIGH (TIM2);
|
||||
else
|
||||
TIM_PWM_SET_CH1_POLARITY_ACTIVE_LOW (TIM2);
|
||||
|
||||
TIM2->CCR1 = value;
|
||||
TIM_CH1_FORCE_INACTIVE(TIM2);
|
||||
TIM_CH1_ENABLE(TIM2);
|
||||
}
|
||||
|
||||
void TIM2_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM2->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC2M_Pos) | TIM_CCMR1_OC2PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH2_POLARITY_ACTIVE_HIGH (TIM2);
|
||||
else
|
||||
TIM_PWM_SET_CH2_POLARITY_ACTIVE_LOW (TIM2);
|
||||
|
||||
TIM2->CCR2 = value;
|
||||
TIM_CH2_FORCE_INACTIVE(TIM2);
|
||||
TIM_CH2_ENABLE(TIM2);
|
||||
}
|
||||
|
||||
void TIM2_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM2->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC3M_Pos) | TIM_CCMR2_OC3PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH3_POLARITY_ACTIVE_HIGH (TIM2);
|
||||
else
|
||||
TIM_PWM_SET_CH3_POLARITY_ACTIVE_LOW (TIM2);
|
||||
|
||||
TIM2->CCR3 = value;
|
||||
TIM_CH3_ENABLE(TIM2);
|
||||
}
|
||||
|
||||
void TIM2_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM2->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC4M_Pos) | TIM_CCMR2_OC4PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH4_POLARITY_ACTIVE_HIGH (TIM2);
|
||||
else
|
||||
TIM_PWM_SET_CH4_POLARITY_ACTIVE_LOW (TIM2);
|
||||
|
||||
TIM2->CCR4 = value;
|
||||
TIM_CH4_ENABLE(TIM2);
|
||||
}
|
||||
|
||||
void TIM2_pwm_init (void) {
|
||||
|
||||
RCC_TIM2_CLK_ENABLE ();
|
||||
|
||||
TIM2->CR1 = 0x0000;
|
||||
TIM2->CR2 = 0x0000;
|
||||
TIM2->SMCR = 0x0000;
|
||||
TIM2->DIER = 0x0000;
|
||||
|
||||
// disable all channels
|
||||
TIM2->CCER = 0x0000;
|
||||
|
||||
// force CH1 and CH2 inactive, enable compare PRELOAD
|
||||
TIM2->CCMR1 = 0x0000;
|
||||
TIM2->CCMR2 = 0x0000;
|
||||
// reset counter
|
||||
TIM2->CNT = 0x0000;
|
||||
//set PRESCALER
|
||||
TIM2->PSC = TIM2_PSC;
|
||||
// set PERIOD
|
||||
TIM2->ARR = TIM2_PERIOD;
|
||||
|
||||
// reset all PWM periods
|
||||
TIM2->CCR1 = 0x0000;
|
||||
TIM2->CCR2 = 0x0000;
|
||||
TIM2->CCR3 = 0x0000;
|
||||
TIM2->CCR4 = 0x0000;
|
||||
|
||||
TIM_COUNTER_ENABLE (TIM2);
|
||||
}
|
||||
|
||||
/*GPIO_AF_PP (TIM2_PWM_CH1);
|
||||
GPIO_AF_PP (TIM2_PWM_CH2);
|
||||
GPIO_AF_PP (TIM2_PWM_CH3);
|
||||
GPIO_AF_PP (TIM2_PWM_CH4);
|
||||
|
||||
GPIO_SET_AFRL (TIM2_PWM_CH1, GPIO_AF_TIM2);
|
||||
GPIO_SET_AFRL (TIM2_PWM_CH2, GPIO_AF_TIM2);
|
||||
GPIO_SET_AFRL (TIM2_PWM_CH3, GPIO_AF_TIM2);
|
||||
GPIO_SET_AFRL (TIM2_PWM_CH4, GPIO_AF_TIM2);*/
|
||||
|
||||
|
||||
|
||||
#elif defined(tim2_ic)
|
||||
|
||||
void TIM2_init(void) {
|
||||
|
||||
RCC_TIM2_CLK_ENABLE();
|
||||
RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
|
||||
/* =============== configure GPIO ================*/
|
||||
|
||||
GPIO_AF_PP (TIM2_IN_CH2);
|
||||
GPIO_SET_AFRL (TIM2_IN_CH2, 0x02);
|
||||
|
||||
|
||||
/* ====== configure timer capture channels ======*/
|
||||
|
||||
// configure channel 2 as input capture with filter 3
|
||||
TIM2->CCMR1 = (3 << TIM_CCMR1_IC2F_Pos) | (0b01 << TIM_CCMR1_CC2S_Pos);
|
||||
// capture on falling edge only, enable channel
|
||||
TIM2->CCER = TIM_CCER_CC2P | TIM_CCER_CC2E;
|
||||
|
||||
/* Configure base timer */
|
||||
|
||||
// enable interrupt on timer update and on channel2 input capture
|
||||
TIM2->DIER = TIM_DIER_UIE | TIM_DIER_CC2IE;
|
||||
|
||||
TIM2->PSC = TIM2_PSC; // 54;
|
||||
TIM2->ARR = TIM2_PERIOD; // 65535;
|
||||
|
||||
// request UEV event only on underflow/overflow and enable timer
|
||||
TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
|
||||
|
||||
// set highest priority since the handler is a non blocking function
|
||||
NVIC_SetPriority(TIM2_IRQn, 0);
|
||||
NVIC_EnableIRQ(TIM2_IRQn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
__attribute__ ((weak)) void TIM2_IRQHandler (void) {
|
||||
|
||||
// clear IT flag
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
283
tim3.c
Normal file
283
tim3.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* tim3.c
|
||||
*
|
||||
* Created on: Dec 30, 2023
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
|
||||
#include "main.h"
|
||||
#include "mcu.h"
|
||||
#include "gpio.h"
|
||||
|
||||
|
||||
#ifdef tim3_adc_timebase
|
||||
|
||||
|
||||
void TIM3_init (void) {
|
||||
|
||||
RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
|
||||
TIM3->CR1 = 0x0000;
|
||||
TIM3->CR2 = (0b010 << TIM_CR2_MMS_Pos);
|
||||
TIM3->DIER = 0x0000; // disable all interrupt requests
|
||||
|
||||
TIM3->PSC = 24-1;
|
||||
TIM3->ARR = 1000 -1;
|
||||
|
||||
|
||||
TIM3->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef tim3_pwm
|
||||
|
||||
|
||||
void TIM3_pwm_config_ch1 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM3->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH1_POLARITY_ACTIVE_HIGH (TIM3);
|
||||
else
|
||||
TIM_PWM_SET_CH1_POLARITY_ACTIVE_LOW (TIM3);
|
||||
|
||||
TIM3->CCR1 = value;
|
||||
TIM_CH1_FORCE_INACTIVE(TIM3);
|
||||
TIM_CH1_ENABLE(TIM3);
|
||||
}
|
||||
|
||||
void TIM3_pwm_config_ch2 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM3->CCMR1 = (TIM_FORCE_INACTIVE << TIM_CCMR1_OC2M_Pos) | TIM_CCMR1_OC2PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH2_POLARITY_ACTIVE_HIGH (TIM3);
|
||||
else
|
||||
TIM_PWM_SET_CH2_POLARITY_ACTIVE_LOW (TIM3);
|
||||
|
||||
TIM3->CCR2 = value;
|
||||
TIM_CH2_FORCE_INACTIVE(TIM3);
|
||||
TIM_CH2_ENABLE(TIM3);
|
||||
}
|
||||
|
||||
void TIM3_pwm_config_ch3 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM3->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC3M_Pos) | TIM_CCMR2_OC3PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH3_POLARITY_ACTIVE_HIGH (TIM3);
|
||||
else
|
||||
TIM_PWM_SET_CH3_POLARITY_ACTIVE_LOW (TIM3);
|
||||
|
||||
TIM3->CCR3 = value;
|
||||
TIM_CH3_ENABLE(TIM3);
|
||||
}
|
||||
|
||||
void TIM3_pwm_config_ch4 (TIM_OC_ACTIVE_STATE_enum activeState, u16 value) {
|
||||
TIM3->CCMR2 = (TIM_FORCE_INACTIVE << TIM_CCMR2_OC4M_Pos) | TIM_CCMR2_OC4PE;
|
||||
|
||||
if (activeState == TIM_OC_ACTIVE_HIGH)
|
||||
TIM_PWM_SET_CH4_POLARITY_ACTIVE_HIGH (TIM3);
|
||||
else
|
||||
TIM_PWM_SET_CH4_POLARITY_ACTIVE_LOW (TIM3);
|
||||
|
||||
TIM3->CCR4 = value;
|
||||
TIM_CH4_ENABLE(TIM3);
|
||||
}
|
||||
|
||||
void TIM3_pwm_init (void) {
|
||||
|
||||
RCC_TIM3_CLK_ENABLE ();
|
||||
|
||||
TIM3->CR1 = 0x0000;
|
||||
TIM3->CR2 = 0x0000;
|
||||
TIM3->SMCR = 0x0000;
|
||||
TIM3->DIER = 0x0000;
|
||||
|
||||
|
||||
// disable all channels
|
||||
TIM3->CCER = 0x0000;
|
||||
|
||||
// enable ch3 and ch4, force them inactive
|
||||
TIM3->CCMR1 = 0x0000;
|
||||
TIM3->CCMR2 = 0x0000;
|
||||
|
||||
|
||||
// reset counter
|
||||
TIM3->CNT = 0x0000;
|
||||
//set PRESCALER
|
||||
TIM3->PSC = TIM3_PSC;
|
||||
// set PERIOD
|
||||
TIM3->ARR = TIM3_PERIOD;
|
||||
|
||||
// reset all PWM periods
|
||||
TIM3->CCR1 = 0x0000;
|
||||
TIM3->CCR2 = 0x0000;
|
||||
TIM3->CCR3 = 0x0000;
|
||||
TIM3->CCR4 = 0x0000;
|
||||
|
||||
TIM_COUNTER_ENABLE (TIM3);
|
||||
}
|
||||
|
||||
|
||||
#elif defined(tim3_ic)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void TIM3_ic_config_ch1 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
|
||||
// disable channel
|
||||
TIM3->CCER &= ~TIM_CCER_CC1E;
|
||||
|
||||
TIM3->CCMR1 = ((filterValue & 0x0f) << TIM_CCMR1_IC1F_Pos) | (0b01 << TIM_CCMR1_CC1S_Pos);
|
||||
|
||||
// clear edge selection bit => default rising edge
|
||||
TIM3->CCER &= ~(TIM_CCER_CC1NP | TIM_CCER_CC1P);
|
||||
switch (activeState) {
|
||||
case TIM_IC_ACTIVE_RISING:
|
||||
break;
|
||||
case TIM_IC_ACTIVE_FALLING:
|
||||
TIM3->CCER |= TIM_CCER_CC1P;
|
||||
break;
|
||||
case TIM_IC_ACTIVE_BOTH:
|
||||
TIM3->CCER |= (TIM_CCER_CC1NP | TIM_CCER_CC1P);
|
||||
break;
|
||||
}
|
||||
|
||||
// enable interrupt on channel compare
|
||||
TIM3->DIER |= TIM_DIER_CC1IE;
|
||||
|
||||
// enable the channel
|
||||
TIM3->CCER |= TIM_CCER_CC1E;
|
||||
}
|
||||
|
||||
void TIM3_ic_config_ch2 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
|
||||
// disable channel
|
||||
TIM3->CCER &= ~TIM_CCER_CC2E;
|
||||
|
||||
TIM3->CCMR1 = ((filterValue & 0x0f) << TIM_CCMR1_IC2F_Pos) | (0b01 << TIM_CCMR1_CC2S_Pos);
|
||||
|
||||
// clear edge selection bit => default rising edge
|
||||
TIM3->CCER &= ~(TIM_CCER_CC2NP | TIM_CCER_CC2P);
|
||||
switch (activeState) {
|
||||
case TIM_IC_ACTIVE_RISING:
|
||||
break;
|
||||
case TIM_IC_ACTIVE_FALLING:
|
||||
TIM3->CCER |= TIM_CCER_CC2P;
|
||||
break;
|
||||
case TIM_IC_ACTIVE_BOTH:
|
||||
TIM3->CCER |= (TIM_CCER_CC2NP | TIM_CCER_CC2P);
|
||||
break;
|
||||
}
|
||||
|
||||
// enable interrupt on channel compare
|
||||
TIM3->DIER |= TIM_DIER_CC2IE;
|
||||
|
||||
// enable the channel
|
||||
TIM3->CCER |= TIM_CCER_CC2E;
|
||||
}
|
||||
|
||||
void TIM3_ic_config_ch3 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
|
||||
// disable channel
|
||||
TIM3->CCER &= ~TIM_CCER_CC3E;
|
||||
|
||||
TIM3->CCMR2 = ((filterValue & 0x0f) << TIM_CCMR2_IC3F_Pos) | (0b01 << TIM_CCMR2_CC3S_Pos);
|
||||
|
||||
// clear edge selection bit => default rising edge
|
||||
TIM3->CCER &= ~(TIM_CCER_CC3NP | TIM_CCER_CC3P);
|
||||
switch (activeState) {
|
||||
case TIM_IC_ACTIVE_RISING:
|
||||
break;
|
||||
case TIM_IC_ACTIVE_FALLING:
|
||||
TIM3->CCER |= TIM_CCER_CC3P;
|
||||
break;
|
||||
case TIM_IC_ACTIVE_BOTH:
|
||||
TIM3->CCER |= (TIM_CCER_CC3NP | TIM_CCER_CC3P);
|
||||
break;
|
||||
}
|
||||
|
||||
// enable interrupt on channel compare
|
||||
TIM3->DIER |= TIM_DIER_CC3IE;
|
||||
|
||||
// enable the channel
|
||||
TIM3->CCER |= TIM_CCER_CC3E;
|
||||
}
|
||||
|
||||
void TIM3_ic_config_ch4 (TIM_IC_ACTIVE_EDGE_enum activeState, u8 filterValue) {
|
||||
// disable channel
|
||||
TIM3->CCER &= ~TIM_CCER_CC3E;
|
||||
|
||||
TIM3->CCMR2 = ((filterValue & 0x0f) << TIM_CCMR2_IC4F_Pos) | (0b01 << TIM_CCMR2_CC4S_Pos);
|
||||
|
||||
// clear edge selection bit => default rising edge
|
||||
TIM3->CCER &= ~(TIM_CCER_CC4NP | TIM_CCER_CC4P);
|
||||
switch (activeState) {
|
||||
case TIM_IC_ACTIVE_RISING:
|
||||
break;
|
||||
case TIM_IC_ACTIVE_FALLING:
|
||||
TIM3->CCER |= TIM_CCER_CC4P;
|
||||
break;
|
||||
case TIM_IC_ACTIVE_BOTH:
|
||||
TIM3->CCER |= (TIM_CCER_CC4NP | TIM_CCER_CC4P);
|
||||
break;
|
||||
}
|
||||
|
||||
// enable interrupt on channel compare
|
||||
TIM3->DIER |= TIM_DIER_CC4IE;
|
||||
|
||||
// enable the channel
|
||||
TIM3->CCER |= TIM_CCER_CC4E;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TIM3_ic_init(void) {
|
||||
|
||||
RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
TIM3->CCMR1 = 0x00000000;
|
||||
TIM3->CCMR2 = 0x00000000;
|
||||
|
||||
|
||||
/* Configure base timer */
|
||||
// enable interrupt on timer update
|
||||
TIM3->DIER = TIM_DIER_UIE;
|
||||
|
||||
TIM3->PSC = TIM3_PSC;
|
||||
TIM3->ARR = TIM3_PERIOD;
|
||||
|
||||
// request UEV event only on underflow/overflow and enable timer
|
||||
TIM3->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
|
||||
|
||||
// set highest priority since the handler is a non blocking function
|
||||
NVIC_SetPriority(TIM3_IRQn, 0);
|
||||
NVIC_EnableIRQ(TIM3_IRQn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
__attribute__ ((weak)) void TIM3_IRQHandler (void) {
|
||||
|
||||
// clear IT flag
|
||||
if ((TIM3->SR & TIM_SR_CC1IF) != 0)
|
||||
TIM3->SR &= ~TIM_SR_CC1IF;
|
||||
|
||||
if ((TIM3->SR & TIM_SR_CC2IF) != 0)
|
||||
TIM3->SR &= ~TIM_SR_CC2IF;
|
||||
|
||||
if ((TIM3->SR & TIM_SR_CC3IF) != 0)
|
||||
TIM3->SR &= ~TIM_SR_CC3IF;
|
||||
|
||||
if ((TIM3->SR & TIM_SR_CC4IF) != 0)
|
||||
TIM3->SR &= ~TIM_SR_CC4IF;
|
||||
|
||||
if ((TIM3->SR & TIM_SR_UIF) != 0)
|
||||
TIM3->SR &= ~TIM_SR_UIF;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
228
usart1.c
Normal file
228
usart1.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* USART1.c
|
||||
*
|
||||
* Created on: Dec 25, 2023
|
||||
* Author: Francesco Gritti
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
#ifdef use_usart1
|
||||
|
||||
#include "mcu.h"
|
||||
#include "usart1.h"
|
||||
|
||||
|
||||
// RX Circular Buffer and pointers
|
||||
#define RX1_BUFFLEN 128 //IMPOSTARE MULTIPLO DI 2 !!!
|
||||
static volatile u8 rx1_Buffer [RX1_BUFFLEN];
|
||||
static volatile u8 rx1_Head = 0;
|
||||
static volatile u8 rx1_Tail = 0;
|
||||
|
||||
// TX Circular Buffer and pointers
|
||||
#define TX1_BUFFLEN 128 //IMPOSTARE MULTIPLO DI 2 !!!
|
||||
static volatile u8 tx1_Buffer [TX1_BUFFLEN];
|
||||
static volatile u8 tx1_Head = 0;
|
||||
static volatile u8 tx1_Tail = 0;
|
||||
|
||||
|
||||
|
||||
__attribute__((weak)) void USART1_rxCallback (void) {}
|
||||
|
||||
|
||||
|
||||
|
||||
static void tx1_BufferOverflow () {
|
||||
// do something
|
||||
}
|
||||
|
||||
static void rx1_BufferOverflow () {
|
||||
|
||||
//while (1);
|
||||
}
|
||||
|
||||
|
||||
/* configure usart1 with gpio as follows:
|
||||
* USART1_TX => PB6
|
||||
* USART1_RX => PB7
|
||||
*/
|
||||
|
||||
void USART1_init (u64 brr) {
|
||||
|
||||
RCC_USART1_CLK_ENABLE ();
|
||||
|
||||
// disable USART since some registers can be written only
|
||||
// when the peripheral is disabled
|
||||
USART_DISABLE (USART1);
|
||||
|
||||
USART1->CR1 = 0;
|
||||
USART1->CR2 = 0;
|
||||
USART1->CR3 = 0;
|
||||
// set PRESCALER to 1
|
||||
USART1->GTPR = 1;
|
||||
// set BAUDRATE
|
||||
USART1->BRR = brr;
|
||||
|
||||
// CONFIGURE GPIO
|
||||
|
||||
GPIO_AF_PP (USART1_TX);
|
||||
GPIO_AF_PP (USART1_RX);
|
||||
|
||||
// SET CORRECT ALTERNATE FUNCTION
|
||||
GPIO_SET_AFRL (USART1_TX, GPIO_AF0_USART1);
|
||||
GPIO_SET_AFRL (USART1_RX, GPIO_AF0_USART1);
|
||||
|
||||
|
||||
NVIC_SetPriority (USART1_IRQn, 1<<4);
|
||||
NVIC_EnableIRQ (USART1_IRQn);
|
||||
|
||||
// enable USART peripheral
|
||||
USART_ENABLE_DATA_RECEIVED_INT (USART1);
|
||||
USART_START (USART1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void USART1_disable(void) {
|
||||
__disable_irq();
|
||||
// disable peripheral, transmitter and receiver
|
||||
USART_DISABLE_DATA_RECEIVED_INT (USART1);
|
||||
USART_STOP (USART1);
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void USART1_enable(void) {
|
||||
__disable_irq();
|
||||
// enable peripheral, transmitter and receiver
|
||||
USART_START (USART1);
|
||||
USART_ENABLE_DATA_RECEIVED_INT (USART1);
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
// ISR called when the TX data register is empty. Note that this does NOT mean that the data has been sent and
|
||||
// disabling the peripheral at this point will result in the data not being correctly send out
|
||||
|
||||
|
||||
void USART1_IRQHandler (void) {
|
||||
|
||||
// TX register empty interrupt. Check that TXE interrupt is actually enabled
|
||||
// since after the last byte of a buffer is transferred this bit remains
|
||||
// set since data register is empty
|
||||
if ((USART1->CR1 & USART_CR1_TXEIE) != 0 && (USART1->ISR & USART_ISR_TXE) != 0) {
|
||||
tx1_Tail = (tx1_Tail+1) & (TX1_BUFFLEN-1);
|
||||
|
||||
if (tx1_Tail != tx1_Head) {
|
||||
// if other data need to be transmitted, write to the TX register. This
|
||||
// clears TX register empty interrupt
|
||||
USART_SET_TRANSMIT_DATA (USART1, tx1_Buffer[tx1_Tail]);
|
||||
}
|
||||
else {
|
||||
// if no more data has to be transmitted, disable TX register empty interrupt
|
||||
USART_DISABLE_TX_DATA_REGISTER_EMPTY_INT (USART1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// RX data received interrupt
|
||||
else if ((USART1->ISR & USART_ISR_RXNE) != 0) {
|
||||
|
||||
// read data. This clears interrupt flag
|
||||
u8 dataByte = USART1->RDR;
|
||||
// temporary increment
|
||||
u8 rx1_HeadTemp = (rx1_Head+1) & (RX1_BUFFLEN-1);
|
||||
|
||||
if (rx1_HeadTemp != rx1_Tail) {
|
||||
rx1_Buffer [rx1_Head] = dataByte;
|
||||
rx1_Head = rx1_HeadTemp;
|
||||
USART1_rxCallback ();
|
||||
}
|
||||
else {
|
||||
rx1_BufferOverflow ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void USART1_flush () {
|
||||
|
||||
// wait until all data are set into TX register and last data is fully transmitted
|
||||
while (tx1_Head != tx1_Tail || (USART1->ICR & USART_ISR_TC) == 0)
|
||||
__asm volatile ("NOP");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void USART1_putch (char c) {
|
||||
|
||||
// temporarily increment head pointer
|
||||
u8 tx1_HeadTemp = (tx1_Head+1) & (TX1_BUFFLEN-1);
|
||||
|
||||
// if the TX buffer is full, wait until some data is transmitted
|
||||
if (tx1_HeadTemp == tx1_Tail)
|
||||
tx1_BufferOverflow();
|
||||
while (tx1_HeadTemp == tx1_Tail)
|
||||
__asm volatile ("NOP");
|
||||
|
||||
|
||||
// disable interrupt since it might occur that when in the branch else, the last data is transmitted in between the
|
||||
// write of the new data to the buffer and the increment of the head pointer. In this case the ISR would disable the
|
||||
// peripheral and the new data wouldn't be transmitted
|
||||
|
||||
|
||||
// disable data register empty interrupt enable
|
||||
USART_DISABLE_TX_DATA_REGISTER_EMPTY_INT (USART1);
|
||||
if (tx1_Head == tx1_Tail) { // empty buffer
|
||||
tx1_Buffer [tx1_Head] = c;
|
||||
tx1_Head=(tx1_Head+1) & (TX1_BUFFLEN-1);
|
||||
|
||||
USART_SET_TRANSMIT_DATA (USART1, tx1_Buffer[tx1_Tail]);
|
||||
USART_ENABLE_TX_DATA_REGISTER_EMPTY_INT (USART1);
|
||||
}
|
||||
|
||||
else { // data transmission is already occurring, just add data to the buffer
|
||||
tx1_Buffer [tx1_Head]=c;
|
||||
tx1_Head=(tx1_Head+1) & (TX1_BUFFLEN-1);
|
||||
|
||||
USART_ENABLE_TX_DATA_REGISTER_EMPTY_INT (USART1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void USART1_puts(const char * c) {
|
||||
|
||||
while ((*c)>0)
|
||||
USART1_putch(*c++);
|
||||
}
|
||||
|
||||
|
||||
void USART1_nputs(const char * c, u16 i) {
|
||||
while (i-- > 0)
|
||||
USART1_putch (*c++);
|
||||
}
|
||||
|
||||
|
||||
u8 USART1_getch (char* c) {
|
||||
|
||||
if (rx1_Tail != rx1_Head) {
|
||||
*c = rx1_Buffer [rx1_Tail];
|
||||
rx1_Tail = (rx1_Tail+1) & (RX1_BUFFLEN-1);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u16 USART1_available (void) {
|
||||
|
||||
i32 N = rx1_Head-rx1_Tail;
|
||||
if (N<0) N += RX1_BUFFLEN;
|
||||
return (u16) N;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
60
usart1.h
Normal file
60
usart1.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* usart1.h
|
||||
*
|
||||
* Created on: Dec 25, 2023
|
||||
* Author: Francesco Gritti
|
||||
|
||||
|
||||
===== EXAMPLE USAGE ======================
|
||||
|
||||
int main(void) {
|
||||
|
||||
clock_config();
|
||||
USART1_init (115200);
|
||||
|
||||
__enable_irq();
|
||||
|
||||
while (1) {
|
||||
|
||||
flib_printf ("USART demo\n");
|
||||
HAL_Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void USART1_rxCallback (void) {
|
||||
// echo back received characters
|
||||
char c;
|
||||
while (USART1_getch (&c)){
|
||||
USART1_putch (c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef USART1_h
|
||||
#define USART1_h
|
||||
|
||||
|
||||
#include "ftypes.h"
|
||||
|
||||
|
||||
|
||||
void USART1_init (u64 baudrate);
|
||||
void USART1_disable (void);
|
||||
void USART1_enable (void);
|
||||
void USART1_putch (char c);
|
||||
void USART1_puts (const char * s);
|
||||
void USART1_nputs (const char * s, u16 i);
|
||||
void USART1_flush ();
|
||||
void USART1_rxCallback (void);
|
||||
|
||||
|
||||
u8 USART1_getch (char * c);
|
||||
u16 USART1_available (void);
|
||||
|
||||
|
||||
|
||||
#endif /* USART1_h */
|
Loading…
Reference in New Issue
Block a user