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