修改了Web后台的部分界面,增加了HAmqtt中的总电量传感器,后台新增mqtt上报频率设置

This commit is contained in:
OOP
2025-03-03 21:49:41 +08:00
parent e1e00b60ce
commit 9f9d4c7a56
4468 changed files with 1473046 additions and 10728 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,649 @@
/**************************************************************************//**
* @file core_cm4_simd.h
* @brief CMSIS Cortex-M4 SIMD Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM4_SIMD_H
#define __CORE_CM4_SIMD_H
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#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) )
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_iar.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
#include <cmsis_ccs.h>
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SMLALD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLALDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SMLSLD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
#define __SMLSLDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
/* not yet supported */
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CORE_CM4_SIMD_H */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,618 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#else
(void)fpscr;
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@@ -0,0 +1,618 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return((int32_t)result);
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@@ -0,0 +1,25 @@
/**
******************************************************************************
* @file crt0.h
* @author William Xu
* @version V1.0.0
* @date 16-Sep-2014
* @brief This file provides functions called by MICO for initialization.
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#pragma once
extern int main( void );
extern void init_clocks( void );
extern void init_memory( void );
extern void init_architecture( void );
extern void init_platform( void );

View File

@@ -0,0 +1,52 @@
/**
******************************************************************************
* @file crt0_EWARM.h
* @author William Xu
* @version V1.0.0
* @date 16-Sep-2014
* @brief __low_level_init called by IAR before main.
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#include "platform.h"
#include "crt0.h"
extern void* app_hdr_start_addr_loc;
#define SCB_VTOR_ADDRESS ( ( volatile unsigned long* ) 0xE000ED08 )
#define APP_HDR_START_ADDR ((unsigned char*)&app_hdr_start_addr_loc)
int __low_level_init( void );
/* This is the code that gets called on processor reset. To initialize the */
/* device. */
#pragma section=".intvec"
#pragma section=".intvec_RAM"
int __low_level_init( void )
{
extern void init_clocks(void);
extern void init_memory(void);
/* IAR allows init functions in __low_level_init(), but it is run before global
* variables have been initialised, so the following init still needs to be done
* When using GCC, this is done in crt0_GCC.c
*/
#ifdef BOOTLOADER
/* Set the Vector Table base location at 0x20000000 */
//*SCB_VTOR_ADDRESS = 0x20000000;
*SCB_VTOR_ADDRESS = (unsigned long )__section_begin(".intvec_RAM");
#else
/* Setup the interrupt vectors address */
*SCB_VTOR_ADDRESS = (unsigned long )__section_begin(".intvec");
init_clocks();
init_memory();
#endif
return 1; /* return 1 to force memory init */
}

View File

@@ -0,0 +1,188 @@
/**
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
*
*/
#include <string.h>
#include "platform_init.h"
#include "platform_cmsis.h"
#include "platform_toolchain.h"
#define SCB_AIRCR_VECTKEY ( (unsigned long)( 0x5FA << SCB_AIRCR_VECTKEY_Pos ))
extern void * link_global_data_initial_values;
extern void * link_global_data_start;
extern void * link_global_data_end;
#define link_global_data_size ((unsigned long)&link_global_data_end - (unsigned long)&link_global_data_start)
extern void * link_run_from_ram_code_flash_location;
extern void * link_run_from_ram_code_ram_location;
extern void * link_run_from_ram_code_ram_end;
#define link_run_from_ram_code_size ((unsigned long)&link_run_from_ram_code_ram_end - (unsigned long)&link_run_from_ram_code_ram_location)
extern void * link_interrupt_vectors_location;
extern void * link_bss_location;
extern void * link_bss_end;
#define link_bss_size ((unsigned long)&link_bss_end - (unsigned long)&link_bss_location )
#ifdef DEBUG
extern void * link_stack_location;
extern void * link_stack_end;
#define link_stack_size ((unsigned long)&link_stack_end - (unsigned long)&link_stack_location )
#endif /* ifdef DEBUG */
typedef void (*constructor_ptr_t)( void );
extern constructor_ptr_t link_constructors_location[];
extern constructor_ptr_t link_constructors_end;
/* Must be naked to avoid overwriting a program which is in RAM during function prologue when stack pointer is invalid */
void _start( void ) __attribute__ (( naked ));
void _start_init( void ) __attribute__ (( naked ));
void _exit( int status );
#define link_constructors_size ((unsigned long)&link_constructors_end - (unsigned long)&link_constructors_location )
__attribute__((section(".copy_ramcode"))) void _start(void)
{
/* Copy from flash any code to be run from RAM. */
uint32_t *dest = (uint32_t *)&link_run_from_ram_code_ram_location;
uint32_t *src = (uint32_t *)&link_run_from_ram_code_flash_location;
uint32_t i = 0;
/* Do not use memcpy, memcpy may be linked in ram */
if ( (&link_run_from_ram_code_ram_location != &link_run_from_ram_code_flash_location) && ( link_run_from_ram_code_size != 0) )
{
for ( i = 0; i < link_run_from_ram_code_size; i++ )
{
dest[i] = src[i];
}
}
__asm volatile(
" ldr r0, =_start_init \n\t"
" bx r0 \n\t");
}
void _start_init( void )
{
unsigned long ctor_num;
/* Stack pointer is usually set up by boot process, but if program was loaded via jtag in RAM, that might not have happened */
__asm__( " ldr r1, =link_stack_end\n"
" mov sp, r1\n"
);
/* Setup the interrupt vectors address */
SCB->VTOR = (unsigned long) &link_interrupt_vectors_location;
/* Enable CPU Cycle counting */
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
/* Initialise clocks and memory. init_clocks() and init_memory() must NOT depend on globals as global data and bss sections aren't initialised yet */
init_clocks();
init_memory();
/* Copy initial values for global variables into RAM */
if ( ( &link_global_data_start != &link_global_data_initial_values ) && ( link_global_data_size != 0 ) )
{
memcpy( &link_global_data_start, &link_global_data_initial_values, (size_t) link_global_data_size );
}
/* BSS segment is for zero initialised elements, so memset it to zero */
memset( &link_bss_location, 0, (size_t) link_bss_size );
#if 0 /* was ifdef DEBUG */
/* This is not a valid way to fill the stack, since it is currently in use - causes a problem in release with debug on - optimisation of active stack overwriting causes hardfault */
memset( &link_stack_location, 0xA5, link_stack_size ); /* Fill stack with pattern to allow checking of stack usage */
#endif /* if 0 */
/*
* Run global C++ constructors if any
*/
/* TODO: make this an unconditional goto?, so that return address stuff doesn't get put on the stack. (what happens if main returns in this case?) */
init_architecture();
init_platform();
for ( ctor_num = 0; ctor_num < link_constructors_size/sizeof(constructor_ptr_t); ctor_num++ )
{
link_constructors_location[ctor_num]();
}
main( );
/* the main loop has returned - there is now nothing to do - reboot. */
/* Reset request */
SCB->AIRCR = SCB_AIRCR_SYSRESETREQ_Msk | SCB_AIRCR_VECTKEY;
}
void _exit( int status )
{
/* the main loop has returned - there is now nothing to do - reboot. */
/* Allow some time for any printf calls to complete */
volatile unsigned int i; /* try to make this not get optimized out by declaring the variable as volatile */
volatile unsigned int j; /* try to make this not get optimized out by declaring the variable as volatile */
(void) status; /* unused parameter */
for ( i = 0; i < (unsigned int) 1000; i++ )
{
for ( j = 0; j < (unsigned int) 10000; j++ )
{
__asm("NOP");
}
}
/* Reset request */
SCB->AIRCR = SCB_AIRCR_SYSRESETREQ_Msk | SCB_AIRCR_VECTKEY;
/* Should never get here, but this will get rid of error: "noreturn function does return" */
while ( 1 == 1 )
{
/* do nothing */
}
}
void _memory_init(void)
{
unsigned long ctor_num;
/* Copy from flash any code to be run from RAM. Setup .fastcode section first in case init_clocks() needs it */
if ( ( &link_run_from_ram_code_ram_location != &link_run_from_ram_code_flash_location ) && ( link_run_from_ram_code_size != 0 ) )
{
memcpy( &link_run_from_ram_code_ram_location, &link_run_from_ram_code_flash_location, (size_t) link_run_from_ram_code_size );
}
/* Copy initial values for global variables into RAM */
if ( ( &link_global_data_start != &link_global_data_initial_values ) && ( link_global_data_size != 0 ) )
{
memcpy( &link_global_data_start, &link_global_data_initial_values, (size_t) link_global_data_size );
}
/* BSS segment is for zero initialised elements, so memset it to zero */
memset( &link_bss_location, 0, (size_t) link_bss_size );
/*
* Run global C++ constructors if any
*/
for ( ctor_num = 0; ctor_num < link_constructors_size/sizeof(constructor_ptr_t); ctor_num++ )
{
link_constructors_location[ctor_num]();
}
}

View File

@@ -0,0 +1,46 @@
/**
******************************************************************************
* @file crt0_RVMDK.h
* @author William Xu
* @version V1.0.0
* @date 16-Sep-2014
* @brief __low_level_init called by IAR before main.
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#include "platform.h"
#include "crt0.h"
extern void* app_hdr_start_addr_loc;
#define SCB_VTOR_ADDRESS ( ( volatile unsigned long* ) 0xE000ED08 )
#define APP_HDR_START_ADDR ((unsigned char*)&app_hdr_start_addr_loc)
extern unsigned long Image$$ER_IROM1$$Base;
int __low_level_init( void );
/* This is the code that gets called on processor reset. To initialize the */
/* device. */
int __low_level_init( void )
{
extern void init_clocks(void);
extern void init_memory(void);
/* IAR allows init functions in __low_level_init(), but it is run before global
* variables have been initialised, so the following init still needs to be done
* When using GCC, this is done in crt0_GCC.c
*/
/* Setup the interrupt vectors address */
*SCB_VTOR_ADDRESS = (unsigned long)&Image$$ER_IROM1$$Base;
init_clocks();
init_memory();
return 1; /* return 1 to force memory init */
}

View File

@@ -0,0 +1,117 @@
/**
******************************************************************************
* @file hardfault.c
* @author William Xu
* @version V1.0.0
* @date 05-May-2014
* @brief This file provide debug information in hardfault.
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#include "stdio.h"
#include "mico.h"
#include "platform_config.h"
extern OSStatus stdio_hardfault( char* data, uint32_t size );
#if defined ( __CC_ARM )
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#include <cmsis_iar.h>
#elif defined ( __GNUC__ )
#endif
void hard_fault_handler_c (unsigned int * hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
char logString[50];
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
sprintf (logString,"\n>>>>>>>>>>>>>>[");
stdio_hardfault( logString, strlen(logString)+1 );
switch(__get_IPSR())
{
case 3:
sprintf (logString, "Hard Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 4:
sprintf (logString, "Memory Manage");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 5:
sprintf (logString, "Bus Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 6:
sprintf (logString, "Usage Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
default:
sprintf (logString, "Unknown Fault %ld", __get_IPSR());
stdio_hardfault( logString, strlen(logString)+1 );
break;
}
sprintf (logString, ",corrupt,dump registers]>>>>>>>>>>>>>>>>>>\n\r");
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R0 = 0x%08x\r\n", stacked_r0);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R1 = 0x%08x\r\n", stacked_r1);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R2 = 0x%08x\r\n", stacked_r2);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R3 = 0x%08x\r\n", stacked_r3);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R12 = 0x%08x\r\n", stacked_r12);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "LR [R14] = 0x%08x subroutine call return address\r\n", stacked_lr);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "PC [R15] = 0x%08X program counter\r\n", stacked_pc);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "PSR = 0x%08X\r\n", stacked_psr);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "BFAR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED38))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "CFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED28))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "HFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED2C))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "DFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED30))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "AFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED3C))));
stdio_hardfault( logString, strlen(logString)+1 );
while (1);
}

View File

@@ -0,0 +1,376 @@
/**
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
*
*/
#include <common.h>
#include "platform_cmsis.h"
//#include "platform_constants.h"
#include "platform_isr.h"
//#include "platform_isr_interface.h"
#include "platform_assert.h"
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#ifdef DEBUG
#define DEBUG_HARDFAULT
#endif /* ifdef DEBUG */
/* Bit Definitions for SCB_CFSR */
#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001)
#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002)
#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008)
#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010)
#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080)
#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100)
#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200)
#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400)
#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800)
#define SCB_CFSR_STKERR ((uint32_t)0x00001000)
#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000)
#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000)
#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000)
#define SCB_CFSR_INVPC ((uint32_t)0x00040000)
#define SCB_CFSR_NOCP ((uint32_t)0x00080000)
#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000)
#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000)
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
typedef struct exception_stacked_registers_struct
{
/* Stacked registers */
uint32_t R0;
uint32_t R1;
uint32_t R2;
uint32_t R3;
uint32_t R12;
uint32_t LR;
uint32_t PC; /* (Return Address) */
uint32_t PSR;
} exception_stacked_registers_t;
typedef enum EXC_RETURN_enum
{
HANDLER_MSP_MSP = 0xF1, /* Return to Handler mode. Exception return gets state from MSP. Execution uses MSP after return. */
THREAD_MSP_MSP = 0xF9, /* Return to Thread mode. Exception return gets state from MSP. Execution uses MSP after return. */
THREAD_PSP_PSP = 0xFD /* Return to Thread mode. Exception return gets state from PSP. Execution uses PSP after return. */
} EXC_RETURN_t;
/******************************************************
* Static Function Declarations
******************************************************/
void HardFaultException_handler( uint32_t MSP, uint32_t PSP, uint32_t LR );
/******************************************************
* Variable Definitions
******************************************************/
/******************************************************
* Function Definitions
******************************************************/
OSStatus stdio_hardfault( char* data, uint32_t size );
#ifdef DEBUG_HARDFAULT
PLATFORM_DEFINE_NAKED_ISR( HardFault_Handler )
{
// __ASM("MRS R0, MSP" );
// __ASM("MRS R1, PSP" );
// __ASM("MOV R2, LR" );
// __ASM("B HardFaultException_handler");
__ASM("TST LR, #4" );
__ASM("ITE EQ" );
__ASM("MRSEQ R0, MSP" );
__ASM("MRSNE R0, PSP" );
__ASM("MOV SP, R0" );
__ASM("B hard_fault_handler_c");
}
void hard_fault_handler_c (unsigned int * hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
char logString[50];
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
sprintf (logString,"\n>>>>>>>>>>>>>>[");
stdio_hardfault( logString, strlen(logString)+1 );
switch(__get_IPSR())
{
case 3:
sprintf (logString, "Hard Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 4:
sprintf (logString, "Memory Manage");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 5:
sprintf (logString, "Bus Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
case 6:
sprintf (logString, "Usage Fault");
stdio_hardfault( logString, strlen(logString)+1 );
break;
default:
sprintf (logString, "Unknown Fault %ld", __get_IPSR());
stdio_hardfault( logString, strlen(logString)+1 );
break;
}
sprintf (logString, ",corrupt,dump registers]>>>>>>>>>>>>>>>>>>\n\r");
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R0 = 0x%08x\r\n", stacked_r0);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R1 = 0x%08x\r\n", stacked_r1);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R2 = 0x%08x\r\n", stacked_r2);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R3 = 0x%08x\r\n", stacked_r3);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "R12 = 0x%08x\r\n", stacked_r12);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "LR [R14] = 0x%08x subroutine call return address\r\n", stacked_lr);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "PC [R15] = 0x%08X program counter\r\n", stacked_pc);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "PSR = 0x%08X\r\n", stacked_psr);
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "BFAR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED38))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "CFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED28))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "HFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED2C))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "DFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED30))));
stdio_hardfault( logString, strlen(logString)+1 );
sprintf (logString, "AFSR = 0x%08lx\r\n", (*((volatile unsigned long *)(0xE000ED3C))));
stdio_hardfault( logString, strlen(logString)+1 );
while (1);
}
#if defined( __GNUC__ ) && ( ! defined( __clang__ ) )
#pragma GCC optimize ("O0")
#endif /* if defined( __GNUC__ ) && ( ! defined( __clang__ ) ) */
void HardFaultException_handler( uint32_t MSP, uint32_t PSP, uint32_t LR )
{
exception_stacked_registers_t* stackframe;
uint32_t MMFAR = 0;
uint32_t BFAR = 0;
/* Get the Link Register value which contains the EXC_RETURN code */
EXC_RETURN_t EXC_RETURN = (EXC_RETURN_t)(LR & 0xff);
/* The location of the stack frame of the offending code is indicated by the EXC_RETURN code */
if ( ( EXC_RETURN & 0x00000004 ) != 0 )
{
stackframe = (exception_stacked_registers_t*) PSP;
}
else
{
stackframe = (exception_stacked_registers_t*) MSP;
}
(void) stackframe; /* may be unused */
/* Disable interrupts - this is so that when debugger continues, it will go to caller, not an interrupt routine */
/* This will mean the system cannot run properly when returning */
__set_PRIMASK( 0x01 );
/* Find cause of hardfault */
if ( ( SCB->HFSR & SCB_HFSR_VECTTBL_Msk ) != 0 )
{
MICO_TRIGGER_BREAKPOINT(); /* Vector Table Hard Fault - Bus fault during vector table read during exception processing. */
}
else if ( ( SCB->HFSR & SCB_HFSR_FORCED_Msk ) != 0 )
{
/* Hard Fault is an escalated fault that was not handled */
/* Need to read the other fault status registers */
if ( ( SCB->CFSR & SCB_CFSR_MMARVALID ) != 0 )
{
/* Memory Management Fault address register is valid - read it. */
MMFAR = SCB->MMFAR;
}
if ( ( SCB->CFSR & SCB_CFSR_BFARVALID ) != 0 )
{
/* Bus Fault address register is valid - read it. */
BFAR = SCB->BFAR;
}
if ( ( SCB->CFSR & SCB_CFSR_IACCVIOL ) != 0 )
{
/* Memory Management Fault */
MICO_TRIGGER_BREAKPOINT(); /* Instruction Access Violation - Attempt to execute an instruction from a region marked Execute Never */
(void) stackframe->LR; /* Check this variable for the jump instruction that jumped to an invalid region */
(void) stackframe->PC; /* Check this variable for the location that was attempted to be executed */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_DACCVIOL ) != 0 )
{
/* Memory Management Fault */
MICO_TRIGGER_BREAKPOINT(); /* Data Access Violation */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
(void) MMFAR; /* Check this variable for the address of the attempted access */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_MUNSTKERR ) != 0 )
{
/* Memory Management Fault */
MICO_TRIGGER_BREAKPOINT(); /* Unstacking fault returning from an exception - stack possibly corrupted during exception handler */
/* New stackframe is not saved in this case */
}
else if ( ( SCB->CFSR & SCB_CFSR_MSTKERR ) != 0 )
{
/* Memory Management Fault */
MICO_TRIGGER_BREAKPOINT(); /* Stacking fault whilst entering an exception - probably a bad stack pointer */
/* Stack frame may be incorrect due to bad stack pointer */
}
else if ( ( SCB->CFSR & SCB_CFSR_IBUSERR ) != 0 )
{
/* Bus Fault */
MICO_TRIGGER_BREAKPOINT(); /* Instruction Bus Error whilst fetching an instruction*/
}
else if ( ( SCB->CFSR & SCB_CFSR_PRECISERR ) != 0 )
{
/* Bus Fault */
MICO_TRIGGER_BREAKPOINT(); /* Precise Data Bus Error - i.e. Data Bus fault at well defined location */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
(void) BFAR; /* Check this variable for the faulting address */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_IMPRECISERR ) != 0 )
{
/* Bus Fault */
MICO_TRIGGER_BREAKPOINT(); /* Imprecise Data Bus Error - i.e. Data Bus fault occurred but details have been lost due to priorities delaying processing of the fault */
/* No fault details are available in this case*/
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_UNSTKERR ) != 0 )
{
/* Bus Fault */
MICO_TRIGGER_BREAKPOINT(); /* Unstacking fault returning from an exception - stack possibly corrupted during exception handler */
/* New stackframe is not saved in this case */
}
else if ( ( SCB->CFSR & SCB_CFSR_STKERR ) != 0 )
{
/* Bus Fault */
MICO_TRIGGER_BREAKPOINT(); /* Stacking fault whilst entering an exception - probably a bad stack pointer */
/* Stack frame may be incorrect due to bad stack pointer */
}
else if ( ( SCB->CFSR & SCB_CFSR_UNDEFINSTR ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* Undefined Instruction Usage fault - probably corrupted memory in code space */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_INVSTATE ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* Invalid State usage fault - This is probably due to a branch with the LSB=0 - i.e. attempt to execute non-thumb code - Illegal use of EPSR was attempted */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_INVPC ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* Invalid PC load usage fault - the EXC_RETURN value in LR was invalid on return from an exception - possibly stack corruption in exception */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_NOCP ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* No Coprocessor usage fault - coprocessor instruction attempted on processor without support for them */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_UNALIGNED ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* Unaligned access usage fault - Unaligned access whilst UNALIGN_TRP bit of SCB_CCR is set, or any unaligned access to LDM, STM, LDRD or STRD */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else if ( ( SCB->CFSR & SCB_CFSR_DIVBYZERO ) != 0 )
{
/* Usage Fault */
MICO_TRIGGER_BREAKPOINT(); /* Divide by zero usage fault */
(void) stackframe->PC; /* Check this variable for the location of the offending instruction */
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
else
{
/* Unknown Fault */
MICO_TRIGGER_BREAKPOINT();
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
}
else
{
/* Unknown Hard Fault cause */
MICO_TRIGGER_BREAKPOINT();
/* You may try stepping past the return of this handler, which may return near the location of the error */
}
(void) MMFAR; /* This is for debug usage and need not be used programmatically */
(void) BFAR; /* This is for debug usage and need not be used programmatically */
}
#if defined( __GNUC__ ) && ( ! defined( __clang__ ) )
#pragma GCC reset_options
#endif /* if defined( __GNUC__ ) && ( ! defined( __clang__ ) ) */
#endif /* ifdef DEBUG_HARDFAULT */

View File

@@ -0,0 +1,88 @@
/**
******************************************************************************
* @file platform_assert.h
* @author William Xu
* @version V1.0.0
* @date 05-May-2014
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#pragma once
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
#ifdef __GNUC__
#define MICO_ASSERTION_FAIL_ACTION() __asm__("bkpt")
#elif defined ( __IAR_SYSTEMS_ICC__ )
#define MICO_ASSERTION_FAIL_ACTION() __asm("bkpt 0")
#elif defined ( __CC_ARM )
#define MICO_ASSERTION_FAIL_ACTION() __asm("bkpt 0")
#endif
#if defined ( __GNUC__ )
#if defined ( __clang__ )
static inline /*@noreturn@*/void MICO_TRIGGER_BREAKPOINT( void ) __attribute__((analyzer_noreturn))
{
__asm__("bkpt");
}
#else
#define MICO_TRIGGER_BREAKPOINT( ) do { __asm__("bkpt"); } while (0)
#endif /* #if defined ( __clang__ ) */
#ifdef NO_VECTORS
#define MICO_DISABLE_INTERRUPTS() do { __asm__("" : : : "memory"); } while (0)
#define MICO_ENABLE_INTERRUPTS() do { __asm__("" : : : "memory"); } while (0)
#else
#define MICO_DISABLE_INTERRUPTS() do { __asm__("CPSID i" : : : "memory"); } while (0)
#define MICO_ENABLE_INTERRUPTS() do { __asm__("CPSIE i" : : : "memory"); } while (0)
#endif
#define CSPR_INTERRUPTS_DISABLED (0x80)
#elif defined ( __IAR_SYSTEMS_ICC__ )
#define MICO_TRIGGER_BREAKPOINT() do { __asm("bkpt 0"); } while (0)
#define MICO_DISABLE_INTERRUPTS() do { __asm("CPSID i"); } while (0)
#define MICO_ENABLE_INTERRUPTS() do { __asm("CPSIE i"); } while (0)
#endif
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/

View File

@@ -0,0 +1,33 @@
/**
******************************************************************************
* @file platform_core.c
* @author William Xu
* @version V1.0.0
* @date 09-Aug-2016
* @brief This file provide functions called by RTOS
******************************************************************************
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
******************************************************************************
*/
#include "platform_cmsis.h"
#include "platform_core.h"
uint32_t platform_get_cycle_count( void )
{
/* From the ARM Cortex-M3 Techinical Reference Manual
* 0xE0001004 DWT_CYCCNT RW 0x00000000 Cycle Count Register */
return DWT->CYCCNT;
}
mico_bool_t platform_is_in_interrupt_context( void )
{
/* From the ARM Cortex-M3 Techinical Reference Manual
* 0xE000ED04 ICSR RW [a] Privileged 0x00000000 Interrupt Control and State Register */
return ( ( SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk ) != 0 ) ? MICO_TRUE : MICO_FALSE;
}

View File

@@ -0,0 +1,137 @@
/**
* UNPUBLISHED PROPRIETARY SOURCE CODE
* Copyright (c) 2016 MXCHIP Inc.
*
* The contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of MXCHIP Corporation.
*
*/
/** @file
* Defines macros for defining and mapping interrupt handlers to the vector table of ARM-Cortex-M3 CPU
*/
#pragma once
//#include "platform_constants.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************
* Macros
******************************************************/
/* Section where IRQ handlers are placed */
#define IRQ_SECTION ".text.irq"
/* Macro for defining an interrupt handler (non-RTOS-aware)
*
* @warning:
* Do NOT call any RTOS primitive functions from here. If you need to call them,
* define your interrupt handler using WWD_RTOS_DEFINE_ISR()
*
* @usage:
* PLATFORM_DEFINE_ISR( my_irq )
* {
* // Do something here
* }
*
*/
#if defined ( __GNUC__ )
/* GCC */
#define PLATFORM_DEFINE_NAKED_ISR( function ) \
void function( void ); \
__attribute__(( naked, interrupt, used, section( IRQ_SECTION ) )) void function( void )
#define PLATFORM_DEFINE_ISR( name ) \
void name( void ); \
__attribute__(( interrupt, used, section( IRQ_SECTION ) )) void name( void )
#elif defined ( __IAR_SYSTEMS_ICC__ )
/* IAR Systems */
#define PLATFORM_DEFINE_ISR( name ) \
void name( void ); \
__irq __root void name( void )
#else
#define PLATFORM_DEFINE_ISR( name )
#endif
/* Macro for mapping a defined function to an interrupt handler declared in
* <MiCO-SDK>/platform/<Arch>/<Family>/platform_vect_table.c
*
* @usage:
* PLATFORM_MAP_ISR( my_irq, USART1_irq )
*/
#if defined( __GNUC__ )
#define PLATFORM_MAP_ISR( function, irq_handler ) \
extern void irq_handler( void ); \
__attribute__(( alias( #function ))) void irq_handler ( void );
#elif defined ( __IAR_SYSTEMS_ICC__ )
#define PLATFORM_MAP_ISR( function, irq_handler ) \
extern void irq_handler( void ); \
_Pragma( TO_STRING( weak irq_handler=function ) )
#else
#define PLATFORM_MAP_ISR( function, irq_handler )
#endif
/* Macro for declaring a default handler for an unhandled interrupt
*
* @usage:
* PLATFORM_SET_DEFAULT_ISR( USART1_irq, default_handler )
*/
#if defined( __GNUC__ )
#define PLATFORM_SET_DEFAULT_ISR( irq_handler, default_handler ) \
__attribute__(( weak, alias( #default_handler ))) void irq_handler ( void );
#elif defined ( __IAR_SYSTEMS_ICC__ )
#define PLATFORM_SET_DEFAULT_ISR( irq_handler, default_handler ) \
_Pragma( TO_STRING( weak irq_handler=default_handler ) )
#else
#define PLATFORM_SET_DEFAULT_ISR( irq_handler, default_handler )
#endif
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
#ifdef __cplusplus
} /*extern "C" */
#endif