mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-20 17:44:20 +08:00
Synwit MCU 采用新的 BSP 框架,将 BSP 与 libraries 分离 (#8432)
This commit is contained in:
@@ -0,0 +1,411 @@
|
||||
/******************************************************************************
|
||||
* @file cachel1_armv7.h
|
||||
* @brief CMSIS Level 1 Cache API for Armv7-M and later
|
||||
* @version V1.0.0
|
||||
* @date 03. March 2020
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_CACHEL1_ARMV7_H
|
||||
#define ARM_CACHEL1_ARMV7_H
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_CacheFunctions Cache Functions
|
||||
\brief Functions that configure Instruction and Data cache.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Cache Size ID Register Macros */
|
||||
#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
|
||||
#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
|
||||
|
||||
#ifndef __SCB_DCACHE_LINE_SIZE
|
||||
#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
|
||||
#endif
|
||||
|
||||
#ifndef __SCB_ICACHE_LINE_SIZE
|
||||
#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Enable I-Cache
|
||||
\details Turns on I-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_EnableICache (void)
|
||||
{
|
||||
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
||||
if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
|
||||
__DSB();
|
||||
__ISB();
|
||||
SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable I-Cache
|
||||
\details Turns off I-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_DisableICache (void)
|
||||
{
|
||||
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
||||
__DSB();
|
||||
__ISB();
|
||||
SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
|
||||
SCB->ICIALLU = 0UL; /* invalidate I-Cache */
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Invalidate I-Cache
|
||||
\details Invalidates I-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_InvalidateICache (void)
|
||||
{
|
||||
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
||||
__DSB();
|
||||
__ISB();
|
||||
SCB->ICIALLU = 0UL;
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief I-Cache Invalidate by address
|
||||
\details Invalidates I-Cache for the given address.
|
||||
I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
|
||||
I-Cache memory blocks which are part of given address + given size are invalidated.
|
||||
\param[in] addr address
|
||||
\param[in] isize size of memory block (in number of bytes)
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (void *addr, int32_t isize)
|
||||
{
|
||||
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
|
||||
if ( isize > 0 ) {
|
||||
int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U));
|
||||
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */;
|
||||
|
||||
__DSB();
|
||||
|
||||
do {
|
||||
SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
|
||||
op_addr += __SCB_ICACHE_LINE_SIZE;
|
||||
op_size -= __SCB_ICACHE_LINE_SIZE;
|
||||
} while ( op_size > 0 );
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Enable D-Cache
|
||||
\details Turns on D-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_EnableDCache (void)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
uint32_t ccsidr;
|
||||
uint32_t sets;
|
||||
uint32_t ways;
|
||||
|
||||
if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */
|
||||
|
||||
SCB->CSSELR = 0U; /* select Level 1 data cache */
|
||||
__DSB();
|
||||
|
||||
ccsidr = SCB->CCSIDR;
|
||||
|
||||
/* invalidate D-Cache */
|
||||
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
|
||||
do {
|
||||
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
|
||||
do {
|
||||
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
|
||||
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
|
||||
#if defined ( __CC_ARM )
|
||||
__schedule_barrier();
|
||||
#endif
|
||||
} while (ways-- != 0U);
|
||||
} while(sets-- != 0U);
|
||||
__DSB();
|
||||
|
||||
SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable D-Cache
|
||||
\details Turns off D-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_DisableDCache (void)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
uint32_t ccsidr;
|
||||
uint32_t sets;
|
||||
uint32_t ways;
|
||||
|
||||
SCB->CSSELR = 0U; /* select Level 1 data cache */
|
||||
__DSB();
|
||||
|
||||
SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
|
||||
__DSB();
|
||||
|
||||
ccsidr = SCB->CCSIDR;
|
||||
|
||||
/* clean & invalidate D-Cache */
|
||||
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
|
||||
do {
|
||||
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
|
||||
do {
|
||||
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
|
||||
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
|
||||
#if defined ( __CC_ARM )
|
||||
__schedule_barrier();
|
||||
#endif
|
||||
} while (ways-- != 0U);
|
||||
} while(sets-- != 0U);
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Invalidate D-Cache
|
||||
\details Invalidates D-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_InvalidateDCache (void)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
uint32_t ccsidr;
|
||||
uint32_t sets;
|
||||
uint32_t ways;
|
||||
|
||||
SCB->CSSELR = 0U; /* select Level 1 data cache */
|
||||
__DSB();
|
||||
|
||||
ccsidr = SCB->CCSIDR;
|
||||
|
||||
/* invalidate D-Cache */
|
||||
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
|
||||
do {
|
||||
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
|
||||
do {
|
||||
SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
|
||||
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
|
||||
#if defined ( __CC_ARM )
|
||||
__schedule_barrier();
|
||||
#endif
|
||||
} while (ways-- != 0U);
|
||||
} while(sets-- != 0U);
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clean D-Cache
|
||||
\details Cleans D-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_CleanDCache (void)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
uint32_t ccsidr;
|
||||
uint32_t sets;
|
||||
uint32_t ways;
|
||||
|
||||
SCB->CSSELR = 0U; /* select Level 1 data cache */
|
||||
__DSB();
|
||||
|
||||
ccsidr = SCB->CCSIDR;
|
||||
|
||||
/* clean D-Cache */
|
||||
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
|
||||
do {
|
||||
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
|
||||
do {
|
||||
SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
|
||||
((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
|
||||
#if defined ( __CC_ARM )
|
||||
__schedule_barrier();
|
||||
#endif
|
||||
} while (ways-- != 0U);
|
||||
} while(sets-- != 0U);
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clean & Invalidate D-Cache
|
||||
\details Cleans and Invalidates D-Cache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
uint32_t ccsidr;
|
||||
uint32_t sets;
|
||||
uint32_t ways;
|
||||
|
||||
SCB->CSSELR = 0U; /* select Level 1 data cache */
|
||||
__DSB();
|
||||
|
||||
ccsidr = SCB->CCSIDR;
|
||||
|
||||
/* clean & invalidate D-Cache */
|
||||
sets = (uint32_t)(CCSIDR_SETS(ccsidr));
|
||||
do {
|
||||
ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
|
||||
do {
|
||||
SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
|
||||
((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
|
||||
#if defined ( __CC_ARM )
|
||||
__schedule_barrier();
|
||||
#endif
|
||||
} while (ways-- != 0U);
|
||||
} while(sets-- != 0U);
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief D-Cache Invalidate by address
|
||||
\details Invalidates D-Cache for the given address.
|
||||
D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity.
|
||||
D-Cache memory blocks which are part of given address + given size are invalidated.
|
||||
\param[in] addr address
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
if ( dsize > 0 ) {
|
||||
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
|
||||
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
|
||||
|
||||
__DSB();
|
||||
|
||||
do {
|
||||
SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
|
||||
op_addr += __SCB_DCACHE_LINE_SIZE;
|
||||
op_size -= __SCB_DCACHE_LINE_SIZE;
|
||||
} while ( op_size > 0 );
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief D-Cache Clean by address
|
||||
\details Cleans D-Cache for the given address
|
||||
D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity.
|
||||
D-Cache memory blocks which are part of given address + given size are cleaned.
|
||||
\param[in] addr address
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
if ( dsize > 0 ) {
|
||||
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
|
||||
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
|
||||
|
||||
__DSB();
|
||||
|
||||
do {
|
||||
SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
|
||||
op_addr += __SCB_DCACHE_LINE_SIZE;
|
||||
op_size -= __SCB_DCACHE_LINE_SIZE;
|
||||
} while ( op_size > 0 );
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief D-Cache Clean and Invalidate by address
|
||||
\details Cleans and invalidates D_Cache for the given address
|
||||
D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity.
|
||||
D-Cache memory blocks which are part of given address + given size are cleaned and invalidated.
|
||||
\param[in] addr address (aligned to 32-byte boundary)
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
|
||||
{
|
||||
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
|
||||
if ( dsize > 0 ) {
|
||||
int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U));
|
||||
uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */;
|
||||
|
||||
__DSB();
|
||||
|
||||
do {
|
||||
SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */
|
||||
op_addr += __SCB_DCACHE_LINE_SIZE;
|
||||
op_size -= __SCB_DCACHE_LINE_SIZE;
|
||||
} while ( op_size > 0 );
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_CacheFunctions */
|
||||
|
||||
#endif /* ARM_CACHEL1_ARMV7_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,283 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.1.0
|
||||
* @date 09. October 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Arm Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Arm Compiler 6.6 LTM (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100)
|
||||
#include "cmsis_armclang_ltm.h"
|
||||
|
||||
/*
|
||||
* Arm Compiler above 6.10.1 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include <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
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
#ifndef __COMPILER_BARRIER
|
||||
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
|
||||
#define __COMPILER_BARRIER() (void)0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __packed__
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
#ifndef __COMPILER_BARRIER
|
||||
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
|
||||
#define __COMPILER_BARRIER() (void)0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <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
|
||||
#ifndef __COMPILER_BARRIER
|
||||
#warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored.
|
||||
#define __COMPILER_BARRIER() (void)0
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.4
|
||||
* @date 23. July 2019
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2019 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 ( 4U) /*!< [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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,275 @@
|
||||
/******************************************************************************
|
||||
* @file mpu_armv7.h
|
||||
* @brief CMSIS MPU API for Armv7-M MPU
|
||||
* @version V5.1.1
|
||||
* @date 10. February 2020
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_MPU_ARMV7_H
|
||||
#define ARM_MPU_ARMV7_H
|
||||
|
||||
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
|
||||
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
|
||||
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
|
||||
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
|
||||
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
|
||||
|
||||
#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
|
||||
#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
|
||||
#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
|
||||
#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
|
||||
#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
|
||||
#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
|
||||
|
||||
/** MPU Region Base Address Register Value
|
||||
*
|
||||
* \param Region The region to be configured, number 0 to 15.
|
||||
* \param BaseAddress The base address for the region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(Region, BaseAddress) \
|
||||
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
|
||||
((Region) & MPU_RBAR_REGION_Msk) | \
|
||||
(MPU_RBAR_VALID_Msk))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attributes
|
||||
*
|
||||
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
|
||||
* \param IsShareable Region is shareable between multiple bus masters.
|
||||
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
|
||||
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
|
||||
((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
|
||||
(((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
|
||||
(((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
|
||||
(((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
|
||||
|
||||
/**
|
||||
* MPU Region Attribute and Size Register Value
|
||||
*
|
||||
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
|
||||
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
|
||||
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
|
||||
* \param SubRegionDisable Sub-region disable field.
|
||||
* \param Size Region size of the region to be configured, for example 4K, 8K.
|
||||
*/
|
||||
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
|
||||
((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
|
||||
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
|
||||
(((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \
|
||||
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
|
||||
(((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
|
||||
(((MPU_RASR_ENABLE_Msk))))
|
||||
|
||||
/**
|
||||
* MPU Region Attribute and Size Register Value
|
||||
*
|
||||
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
|
||||
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
|
||||
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
|
||||
* \param IsShareable Region is shareable between multiple bus masters.
|
||||
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
|
||||
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
|
||||
* \param SubRegionDisable Sub-region disable field.
|
||||
* \param Size Region size of the region to be configured, for example 4K, 8K.
|
||||
*/
|
||||
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
|
||||
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for strongly ordered memory.
|
||||
* - TEX: 000b
|
||||
* - Shareable
|
||||
* - Non-cacheable
|
||||
* - Non-bufferable
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for device memory.
|
||||
* - TEX: 000b (if shareable) or 010b (if non-shareable)
|
||||
* - Shareable or non-shareable
|
||||
* - Non-cacheable
|
||||
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
|
||||
*
|
||||
* \param IsShareable Configures the device memory as shareable or non-shareable.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for normal memory.
|
||||
* - TEX: 1BBb (reflecting outer cacheability rules)
|
||||
* - Shareable or non-shareable
|
||||
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
|
||||
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
|
||||
*
|
||||
* \param OuterCp Configures the outer cache policy.
|
||||
* \param InnerCp Configures the inner cache policy.
|
||||
* \param IsShareable Configures the memory as shareable or non-shareable.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute non-cacheable policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_NOCACHE 0U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-back, write and read allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WB_WRA 1U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-through, no write allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WT_NWA 2U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-back, no write allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WB_NWA 3U
|
||||
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t RBAR; //!< The region base address register value (RBAR)
|
||||
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DMB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DMB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RASR = 0U;
|
||||
}
|
||||
|
||||
/** Configure an MPU region.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
while (cnt > MPU_TYPE_RALIASES) {
|
||||
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
|
||||
table += MPU_TYPE_RALIASES;
|
||||
cnt -= MPU_TYPE_RALIASES;
|
||||
}
|
||||
ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,352 @@
|
||||
/******************************************************************************
|
||||
* @file mpu_armv8.h
|
||||
* @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU
|
||||
* @version V5.1.2
|
||||
* @date 10. February 2020
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_MPU_ARMV8_H
|
||||
#define ARM_MPU_ARMV8_H
|
||||
|
||||
/** \brief Attribute for device memory (outer only) */
|
||||
#define ARM_MPU_ATTR_DEVICE ( 0U )
|
||||
|
||||
/** \brief Attribute for non-cacheable, normal memory */
|
||||
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
|
||||
|
||||
/** \brief Attribute for normal memory (outer and inner)
|
||||
* \param NT Non-Transient: Set to 1 for non-transient data.
|
||||
* \param WB Write-Back: Set to 1 to use write-back update policy.
|
||||
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
|
||||
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
|
||||
*/
|
||||
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
|
||||
((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U))
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
|
||||
|
||||
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
|
||||
|
||||
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
|
||||
|
||||
/** \brief Memory Attribute
|
||||
* \param O Outer memory attributes
|
||||
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
|
||||
*/
|
||||
#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U)))
|
||||
|
||||
/** \brief Normal memory non-shareable */
|
||||
#define ARM_MPU_SH_NON (0U)
|
||||
|
||||
/** \brief Normal memory outer shareable */
|
||||
#define ARM_MPU_SH_OUTER (2U)
|
||||
|
||||
/** \brief Normal memory inner shareable */
|
||||
#define ARM_MPU_SH_INNER (3U)
|
||||
|
||||
/** \brief Memory access permissions
|
||||
* \param RO Read-Only: Set to 1 for read-only memory.
|
||||
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
|
||||
*/
|
||||
#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U))
|
||||
|
||||
/** \brief Region Base Address Register value
|
||||
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
|
||||
* \param SH Defines the Shareability domain for this memory region.
|
||||
* \param RO Read-Only: Set to 1 for a read-only memory region.
|
||||
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
|
||||
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
|
||||
(((BASE) & MPU_RBAR_BASE_Msk) | \
|
||||
(((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
|
||||
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
|
||||
(((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
|
||||
|
||||
/** \brief Region Limit Address Register value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR(LIMIT, IDX) \
|
||||
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
|
||||
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
#if defined(MPU_RLAR_PXN_Pos)
|
||||
|
||||
/** \brief Region Limit Address Register with PXN value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
|
||||
(((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
|
||||
(((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
|
||||
(((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t RBAR; /*!< Region Base Address Register value */
|
||||
uint32_t RLAR; /*!< Region Limit Address Register value */
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DMB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DMB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Enable the Non-secure MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
|
||||
{
|
||||
__DMB();
|
||||
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** Disable the Non-secure MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
|
||||
{
|
||||
__DMB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Set the memory attribute encoding to the given MPU.
|
||||
* \param mpu Pointer to the MPU to be configured.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
|
||||
{
|
||||
const uint8_t reg = idx / 4U;
|
||||
const uint32_t pos = ((idx % 4U) * 8U);
|
||||
const uint32_t mask = 0xFFU << pos;
|
||||
|
||||
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
|
||||
return; // invalid index
|
||||
}
|
||||
|
||||
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
|
||||
}
|
||||
|
||||
/** Set the memory attribute encoding.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Set the memory attribute encoding to the Non-secure MPU.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Clear and disable the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RLAR = 0U;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU, rnr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Clear and disable the given Non-secure MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Configure the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RBAR = rbar;
|
||||
mpu->RLAR = rlar;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Configure the given Non-secure MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table to the given MPU.
|
||||
* \param mpu Pointer to the MPU registers to be used.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
if (cnt == 1U) {
|
||||
mpu->RNR = rnr;
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
|
||||
} else {
|
||||
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
|
||||
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
|
||||
|
||||
mpu->RNR = rnrBase;
|
||||
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
|
||||
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
|
||||
table += c;
|
||||
cnt -= c;
|
||||
rnrOffset = 0U;
|
||||
rnrBase += MPU_TYPE_RALIASES;
|
||||
mpu->RNR = rnrBase;
|
||||
}
|
||||
|
||||
ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Load the given number of MPU regions from a table to the Non-secure MPU.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
/******************************************************************************
|
||||
* @file pmu_armv8.h
|
||||
* @brief CMSIS PMU API for Armv8.1-M PMU
|
||||
* @version V1.0.0
|
||||
* @date 24. March 2020
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2020 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_PMU_ARMV8_H
|
||||
#define ARM_PMU_ARMV8_H
|
||||
|
||||
/**
|
||||
* \brief PMU Events
|
||||
* \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events.
|
||||
* */
|
||||
|
||||
#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */
|
||||
#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */
|
||||
#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */
|
||||
#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */
|
||||
#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */
|
||||
#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */
|
||||
#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */
|
||||
#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */
|
||||
#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */
|
||||
#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */
|
||||
#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */
|
||||
#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */
|
||||
#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */
|
||||
#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */
|
||||
#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */
|
||||
#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */
|
||||
#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */
|
||||
#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */
|
||||
#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */
|
||||
#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */
|
||||
#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */
|
||||
#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */
|
||||
#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */
|
||||
#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */
|
||||
#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */
|
||||
#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */
|
||||
#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */
|
||||
#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */
|
||||
#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */
|
||||
#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */
|
||||
#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */
|
||||
#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */
|
||||
#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */
|
||||
#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */
|
||||
#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */
|
||||
#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */
|
||||
#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */
|
||||
#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */
|
||||
#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */
|
||||
#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */
|
||||
#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */
|
||||
#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */
|
||||
#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */
|
||||
#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */
|
||||
#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */
|
||||
#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */
|
||||
#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */
|
||||
#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */
|
||||
#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */
|
||||
#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */
|
||||
#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */
|
||||
#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */
|
||||
#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */
|
||||
#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */
|
||||
#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */
|
||||
#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */
|
||||
#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */
|
||||
#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */
|
||||
#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */
|
||||
#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */
|
||||
#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */
|
||||
#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */
|
||||
#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */
|
||||
#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */
|
||||
#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */
|
||||
#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */
|
||||
#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */
|
||||
#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */
|
||||
#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */
|
||||
#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */
|
||||
#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */
|
||||
#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */
|
||||
#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */
|
||||
#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */
|
||||
#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */
|
||||
#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */
|
||||
#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */
|
||||
#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */
|
||||
#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */
|
||||
#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */
|
||||
|
||||
/** \brief PMU Functions */
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_Enable(void);
|
||||
__STATIC_INLINE void ARM_PMU_Disable(void);
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type);
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void);
|
||||
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void);
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask);
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask);
|
||||
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void);
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num);
|
||||
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void);
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask);
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask);
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask);
|
||||
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask);
|
||||
|
||||
/**
|
||||
\brief Enable the PMU
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Enable(void)
|
||||
{
|
||||
PMU->CTRL |= PMU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Disable the PMU
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Disable(void)
|
||||
{
|
||||
PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set event to count for PMU eventer counter
|
||||
\param [in] num Event counter (0-30) to configure
|
||||
\param [in] type Event to count
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type)
|
||||
{
|
||||
PMU->EVTYPER[num] = type;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reset cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void)
|
||||
{
|
||||
PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reset all event counters
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void)
|
||||
{
|
||||
PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Enable counters
|
||||
\param [in] mask Counters to enable
|
||||
\note Enables one or more of the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask)
|
||||
{
|
||||
PMU->CNTENSET = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Disable counters
|
||||
\param [in] mask Counters to enable
|
||||
\note Disables one or more of the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask)
|
||||
{
|
||||
PMU->CNTENCLR = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Read cycle counter
|
||||
\return Cycle count
|
||||
*/
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void)
|
||||
{
|
||||
return PMU->CCNTR;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Read event counter
|
||||
\param [in] num Event counter (0-30) to read
|
||||
\return Event count
|
||||
*/
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num)
|
||||
{
|
||||
return PMU->EVCNTR[num];
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Read counter overflow status
|
||||
\return Counter overflow status bits for the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void)
|
||||
{
|
||||
return PMU->OVSSET;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Clear counter overflow status
|
||||
\param [in] mask Counter overflow status bits to clear
|
||||
\note Clears overflow status bits for one or more of the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask)
|
||||
{
|
||||
PMU->OVSCLR = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Enable counter overflow interrupt request
|
||||
\param [in] mask Counter overflow interrupt request bits to set
|
||||
\note Sets overflow interrupt request bits for one or more of the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask)
|
||||
{
|
||||
PMU->INTENSET = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Disable counter overflow interrupt request
|
||||
\param [in] mask Counter overflow interrupt request bits to clear
|
||||
\note Clears overflow interrupt request bits for one or more of the following:
|
||||
- event counters (0-30)
|
||||
- cycle counter
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask)
|
||||
{
|
||||
PMU->INTENCLR = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Software increment event counter
|
||||
\param [in] mask Counters to increment
|
||||
\note Software increment bits for one or more event counters (0-30)
|
||||
*/
|
||||
__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask)
|
||||
{
|
||||
PMU->SWINC = mask;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
* @file tz_context.h
|
||||
* @brief Context Management for Armv8-M TrustZone
|
||||
* @version V1.0.1
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef TZ_CONTEXT_H
|
||||
#define TZ_CONTEXT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef TZ_MODULEID_T
|
||||
#define TZ_MODULEID_T
|
||||
/// \details Data type that identifies secure software modules called by a process.
|
||||
typedef uint32_t TZ_ModuleId_t;
|
||||
#endif
|
||||
|
||||
/// \details TZ Memory ID identifies an allocated memory slot.
|
||||
typedef uint32_t TZ_MemoryId_t;
|
||||
|
||||
/// Initialize secure context memory system
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_InitContextSystem_S (void);
|
||||
|
||||
/// Allocate context memory for calling secure software modules in TrustZone
|
||||
/// \param[in] module identifies software modules called from non-secure mode
|
||||
/// \return value != 0 id TrustZone memory slot identifier
|
||||
/// \return value 0 no memory available or internal error
|
||||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
|
||||
|
||||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Load secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Store secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
|
||||
|
||||
#endif // TZ_CONTEXT_H
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,410 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: system_SWM341.c
|
||||
* 功能说明: SWM341单片机的时钟设置
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.1.0 2017年10月25日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include "SWM341.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 系统时钟设定
|
||||
*****************************************************************************************************************************************/
|
||||
#define SYS_CLK_20MHz 0 //0 内部高频20MHz RC振荡器
|
||||
#define SYS_CLK_2M5Hz 1 //1 内部高频2.5MHz RC振荡器
|
||||
#define SYS_CLK_40MHz 2 //2 内部高频40MHz RC振荡器
|
||||
#define SYS_CLK_5MHz 3 //3 内部高频 5MHz RC振荡器
|
||||
#define SYS_CLK_XTAL 4 //4 外部晶体振荡器(4-32MHz)
|
||||
#define SYS_CLK_XTAL_DIV8 5 //5 外部晶体振荡器(4-32MHz) 8分频
|
||||
#define SYS_CLK_PLL 6 //6 锁相环输出
|
||||
#define SYS_CLK_PLL_DIV8 7 //7 锁相环输出 8分频
|
||||
#define SYS_CLK_32KHz 8 //8 内部低频32KHz RC 振荡器
|
||||
#define SYS_CLK_XTAL_32K 9 //9 外部低频32KHz 晶体振荡器
|
||||
|
||||
#define SYS_CLK SYS_CLK_PLL
|
||||
|
||||
|
||||
#define __HSI (20000000UL) //高速内部时钟
|
||||
#define __LSI ( 32000UL) //低速内部时钟
|
||||
#define __HSE (12000000UL) //高速外部时钟
|
||||
#define __LSE ( 32768UL) //低速外部时钟
|
||||
|
||||
|
||||
/********************************** PLL 设定 **********************************************
|
||||
* VCO输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV
|
||||
* PLL输出频率 = PLL输入时钟 / INDIV * 4 * FBDIV / OUTDIV = VCO输出频率 / OUTDIV
|
||||
* 注意:VCO输出频率需要在 [600MHz, 1400MHz] 之间
|
||||
*****************************************************************************************/
|
||||
#define SYS_PLL_SRC SYS_CLK_XTAL //可取值SYS_CLK_20MHz、SYS_CLK_XTAL
|
||||
|
||||
#define PLL_IN_DIV 3
|
||||
|
||||
#define PLL_FB_DIV 75
|
||||
|
||||
|
||||
#define PLL_OUT_DIV8 0
|
||||
#define PLL_OUT_DIV4 1
|
||||
#define PLL_OUT_DIV2 2
|
||||
|
||||
#define PLL_OUT_DIV PLL_OUT_DIV8
|
||||
|
||||
|
||||
|
||||
uint32_t SystemCoreClock = __HSI; //System Clock Frequency (Core Clock)
|
||||
uint32_t CyclesPerUs = (__HSI / 1000000); //Cycles per micro second
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称:
|
||||
* 功能说明: This function is used to update the variable SystemCoreClock and must be called whenever the core clock is changed
|
||||
* 输 入:
|
||||
* 输 出:
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
if(SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) //SYS <= HRC
|
||||
{
|
||||
if(SYS->HRCCR & SYS_HRCCR_DBL_Msk) //HRC = 40MHz
|
||||
{
|
||||
SystemCoreClock = __HSI*2;
|
||||
}
|
||||
else //HRC = 20MHz
|
||||
{
|
||||
SystemCoreClock = __HSI;
|
||||
}
|
||||
}
|
||||
else //SYS <= CLK
|
||||
{
|
||||
switch((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos)
|
||||
{
|
||||
case 0:
|
||||
SystemCoreClock = __LSI;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if(SYS->PLLCR & SYS_PLLCR_INSEL_Msk) //PLL_IN <= HRC
|
||||
{
|
||||
SystemCoreClock = __HSI;
|
||||
}
|
||||
else //PLL_IN <= XTAL
|
||||
{
|
||||
SystemCoreClock = __HSE;
|
||||
}
|
||||
|
||||
SystemCoreClock = SystemCoreClock / PLL_IN_DIV * PLL_FB_DIV * 4 / (2 << (2 - PLL_OUT_DIV));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
SystemCoreClock = __LSE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
SystemCoreClock = __HSE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
SystemCoreClock = __HSI;
|
||||
if(SYS->HRCCR & SYS_HRCCR_DBL_Msk) SystemCoreClock *= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if(SYS->CLKSEL & SYS_CLKSEL_CLK_DIVx_Msk) SystemCoreClock /= 8;
|
||||
}
|
||||
|
||||
CyclesPerUs = SystemCoreClock / 1000000;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称:
|
||||
* 功能说明: The necessary initializaiton of systerm
|
||||
* 输 入:
|
||||
* 输 出:
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
void SystemInit(void)
|
||||
{
|
||||
SYS->CLKEN0 |= (1 << SYS_CLKEN0_ANAC_Pos);
|
||||
|
||||
Flash_Param_at_xMHz(150);
|
||||
|
||||
switch(SYS_CLK)
|
||||
{
|
||||
case SYS_CLK_20MHz:
|
||||
switchTo20MHz();
|
||||
break;
|
||||
|
||||
case SYS_CLK_2M5Hz:
|
||||
switchTo2M5Hz();
|
||||
break;
|
||||
|
||||
case SYS_CLK_40MHz:
|
||||
switchTo40MHz();
|
||||
break;
|
||||
|
||||
case SYS_CLK_5MHz:
|
||||
switchTo5MHz();
|
||||
break;
|
||||
|
||||
case SYS_CLK_XTAL:
|
||||
switchToXTAL(0);
|
||||
break;
|
||||
|
||||
case SYS_CLK_XTAL_DIV8:
|
||||
switchToXTAL(1);
|
||||
break;
|
||||
|
||||
case SYS_CLK_PLL:
|
||||
switchToPLL(0);
|
||||
break;
|
||||
|
||||
case SYS_CLK_PLL_DIV8:
|
||||
switchToPLL(1);
|
||||
break;
|
||||
|
||||
case SYS_CLK_32KHz:
|
||||
switchTo32KHz();
|
||||
break;
|
||||
|
||||
case SYS_CLK_XTAL_32K:
|
||||
switchToXTAL_32K();
|
||||
break;
|
||||
}
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
if(SystemCoreClock > 120000000)
|
||||
{
|
||||
Flash_Param_at_xMHz(150);
|
||||
}
|
||||
else if(SystemCoreClock > 80000000)
|
||||
{
|
||||
Flash_Param_at_xMHz(120);
|
||||
}
|
||||
else if(SystemCoreClock > 40000000)
|
||||
{
|
||||
Flash_Param_at_xMHz(80);
|
||||
}
|
||||
else if(SystemCoreClock > 30000000)
|
||||
{
|
||||
Flash_Param_at_xMHz(40);
|
||||
}
|
||||
else
|
||||
{
|
||||
Flash_Param_at_xMHz(30);
|
||||
}
|
||||
|
||||
PORTM->PULLD &= ~(1 << PIN1);
|
||||
PORTM->PULLU &= ~((1 << PIN2) | (1 << PIN3));
|
||||
|
||||
SYS->USBPHYCR &= ~SYS_USBPHYCR_OPMODE_Msk;
|
||||
SYS->USBPHYCR |= (1 << SYS_USBPHYCR_OPMODE_Pos); //Non-Driving, DP Pull-Up disable
|
||||
}
|
||||
|
||||
|
||||
void FPU_Enable(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= (0xF << 20);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void delay_3ms(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if(((SYS->CLKSEL & SYS_CLKSEL_SYS_Msk) == 0) &&
|
||||
((((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos) == 0) || //LSI 32KHz
|
||||
(((SYS->CLKSEL & SYS_CLKSEL_CLK_Msk) >> SYS_CLKSEL_CLK_Pos) == 2))) //LSE 32KHz
|
||||
{
|
||||
for(i = 0; i < 20; i++) __NOP();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < 20000; i++) __NOP();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void switchTo20MHz(void)
|
||||
{
|
||||
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
|
||||
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20Hz
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC
|
||||
}
|
||||
|
||||
void switchTo2M5Hz(void)
|
||||
{
|
||||
switchTo20MHz();
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (4 << SYS_CLKSEL_CLK_Pos); //CLK <= HRC
|
||||
|
||||
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC/8
|
||||
}
|
||||
|
||||
void switchTo40MHz(void)
|
||||
{
|
||||
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
|
||||
(1 << SYS_HRCCR_DBL_Pos); //HRC = 40MHz
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL |= (1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC
|
||||
}
|
||||
|
||||
void switchTo5MHz(void)
|
||||
{
|
||||
switchTo40MHz();
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (4 << SYS_CLKSEL_CLK_Pos); //CLK <= HRC
|
||||
|
||||
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= HRC/8
|
||||
}
|
||||
|
||||
void switchToXTAL(uint32_t div8)
|
||||
{
|
||||
switchTo20MHz();
|
||||
|
||||
PORT_Init(PORTA, PIN3, PORTA_PIN3_XTAL_IN, 0);
|
||||
PORT_Init(PORTA, PIN4, PORTA_PIN4_XTAL_OUT, 0);
|
||||
SYS->XTALCR |= (1 << SYS_XTALCR_ON_Pos) | (15 << SYS_XTALCR_DRV_Pos) | (1 << SYS_XTALCR_DET_Pos);
|
||||
|
||||
delay_3ms();
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (3 << SYS_CLKSEL_CLK_Pos); //CLK <= XTAL
|
||||
|
||||
if(div8) SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
else SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= XTAL
|
||||
}
|
||||
|
||||
void switchToPLL(uint32_t div8)
|
||||
{
|
||||
switchTo20MHz();
|
||||
|
||||
PLLInit();
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_Pos); //CLK <= PLL
|
||||
|
||||
if(div8) SYS->CLKSEL |= (1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
else SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= PLL
|
||||
}
|
||||
|
||||
void switchTo32KHz(void)
|
||||
{
|
||||
switchTo20MHz();
|
||||
|
||||
SYS->LRCCR = (1 << SYS_LRCCR_ON_Pos);
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (0 << SYS_CLKSEL_CLK_Pos); //CLK <= LRC
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= LRC
|
||||
}
|
||||
|
||||
void switchToXTAL_32K(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switchTo20MHz();
|
||||
|
||||
SYS->XTALCR |= (1 << SYS_XTALCR_32KON_Pos) | (7 << SYS_XTALCR_32KDRV_Pos) | (1 << SYS_XTALCR_32KDET_Pos);
|
||||
for(i = 0; i < 1000; i++) __NOP();
|
||||
|
||||
SYS->CLKDIVx_ON = 1;
|
||||
|
||||
SYS->CLKSEL &= ~SYS_CLKSEL_CLK_Msk;
|
||||
SYS->CLKSEL |= (2 << SYS_CLKSEL_CLK_Pos); //CLK <= XTAL_32K
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_CLK_DIVx_Pos);
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->CLKSEL &=~(1 << SYS_CLKSEL_SYS_Pos); //SYS <= XTAL_32K
|
||||
}
|
||||
|
||||
void PLLInit(void)
|
||||
{
|
||||
if(SYS_PLL_SRC == SYS_CLK_20MHz)
|
||||
{
|
||||
SYS->HRCCR = (1 << SYS_HRCCR_ON_Pos) |
|
||||
(0 << SYS_HRCCR_DBL_Pos); //HRC = 20Hz
|
||||
|
||||
delay_3ms();
|
||||
|
||||
SYS->PLLCR |= (1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= HRC
|
||||
}
|
||||
else if(SYS_PLL_SRC == SYS_CLK_XTAL)
|
||||
{
|
||||
PORT_Init(PORTA, PIN3, PORTA_PIN3_XTAL_IN, 0);
|
||||
PORT_Init(PORTA, PIN4, PORTA_PIN4_XTAL_OUT, 0);
|
||||
SYS->XTALCR |= (1 << SYS_XTALCR_ON_Pos) | (15 << SYS_XTALCR_DRV_Pos) | (1 << SYS_XTALCR_DET_Pos);
|
||||
|
||||
delay_3ms();
|
||||
delay_3ms();
|
||||
|
||||
SYS->PLLCR &= ~(1 << SYS_PLLCR_INSEL_Pos); //PLL_SRC <= XTAL
|
||||
}
|
||||
|
||||
SYS->PLLDIV &= ~(SYS_PLLDIV_INDIV_Msk |
|
||||
SYS_PLLDIV_FBDIV_Msk |
|
||||
SYS_PLLDIV_OUTDIV_Msk);
|
||||
SYS->PLLDIV |= (PLL_IN_DIV << SYS_PLLDIV_INDIV_Pos) |
|
||||
(PLL_FB_DIV << SYS_PLLDIV_FBDIV_Pos) |
|
||||
(PLL_OUT_DIV<< SYS_PLLDIV_OUTDIV_Pos);
|
||||
|
||||
SYS->PLLCR &= ~(1 << SYS_PLLCR_OFF_Pos);
|
||||
|
||||
while(SYS->PLLLOCK == 0); //等待PLL锁定
|
||||
|
||||
SYS->PLLCR |= (1 << SYS_PLLCR_OUTEN_Pos);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef __SYSTEM_SWM341_H__
|
||||
#define __SYSTEM_SWM341_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
|
||||
extern uint32_t CyclesPerUs; // Cycles per micro second
|
||||
|
||||
|
||||
extern void SystemInit(void);
|
||||
|
||||
extern void SystemCoreClockUpdate (void);
|
||||
|
||||
extern void PLLInit(void);
|
||||
|
||||
extern void switchTo20MHz(void);
|
||||
extern void switchTo2M5Hz(void);
|
||||
extern void switchTo40MHz(void);
|
||||
extern void switchTo5MHz(void);
|
||||
extern void switchToXTAL(uint32_t div8);
|
||||
extern void switchToPLL(uint32_t div8);
|
||||
extern void switchTo32KHz(void);
|
||||
extern void switchToXTAL_32K(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__SYSTEM_SWM341_H__
|
||||
@@ -0,0 +1,23 @@
|
||||
from building import *
|
||||
import rtconfig
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
|
||||
src = Glob('CMSIS/DeviceSupport/*.c')
|
||||
src += Glob('SWM341_StdPeriph_Driver/*.c')
|
||||
|
||||
if rtconfig.CROSS_TOOL == 'gcc':
|
||||
src += ['CMSIS/DeviceSupport/startup/gcc/startup_SWM341.s']
|
||||
elif rtconfig.CROSS_TOOL == 'keil':
|
||||
src += ['CMSIS/DeviceSupport/startup/arm/startup_SWM341.s']
|
||||
elif rtconfig.CROSS_TOOL == 'iar':
|
||||
src += ['CMSIS/DeviceSupport/startup/iar/startup_SWM341.s']
|
||||
|
||||
inc = [cwd + '/CMSIS/CoreSupport',
|
||||
cwd + '/CMSIS/DeviceSupport',
|
||||
cwd + '/SWM341_StdPeriph_Driver'
|
||||
]
|
||||
|
||||
group = DefineGroup('Libraries', src, depend = [''], CPPPATH = inc)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,355 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_adc.c
|
||||
* 功能说明: SWM341单片机的ADC数模转换器功能驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.0.0 2016年1月30日
|
||||
* 升级记录:
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_adc.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Init()
|
||||
* 功能说明: ADC模数转换器初始化
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* ADC_InitStructure * initStruct 包含ADC各相关定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Init(ADC_TypeDef * ADCx, ADC_InitStructure * initStruct)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
switch((uint32_t)ADCx)
|
||||
{
|
||||
case ((uint32_t)ADC0):
|
||||
SYS->CLKSEL &= ~(SYS_CLKSEL_AD0_Msk | SYS_CLKSEL_AD0DIV_Msk);
|
||||
SYS->CLKSEL |= (initStruct->clk_src << SYS_CLKSEL_AD0_Pos);
|
||||
|
||||
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_ADC0_Pos);
|
||||
break;
|
||||
|
||||
case ((uint32_t)ADC1):
|
||||
SYS->CLKSEL &= ~(SYS_CLKSEL_AD1_Msk | SYS_CLKSEL_AD1DIV_Msk);
|
||||
SYS->CLKSEL |= (initStruct->clk_src << SYS_CLKSEL_AD1_Pos);
|
||||
|
||||
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_ADC1_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
ADC_Close(ADCx); //一些关键寄存器只能在ADC关闭时设置
|
||||
|
||||
ADCx->CR |= (1 <<ADC_CR_RESET_Pos);
|
||||
for(i = 0; i < 120*20; i++) __NOP(); //至少2个采样时钟周期
|
||||
ADCx->CR &= ~(1 << ADC_CR_RESET_Pos);
|
||||
|
||||
ADCx->CR |= (0xF << ADC_CR_FFCLR_Pos);
|
||||
ADCx->CR &= ~(0xF << ADC_CR_FFCLR_Pos);
|
||||
|
||||
ADCx->CR &= ~ADC_CR_AVG_Msk;
|
||||
ADCx->CR |= (initStruct->samplAvg << ADC_CR_AVG_Pos);
|
||||
|
||||
ADCx->IE = 0;
|
||||
ADCx->IF = 0x3F3F3F3F; //清除中断标志
|
||||
|
||||
ADCx->IE |= (((initStruct->EOC_IEn & ADC_SEQ0) ? 1 : 0) << ADC_IE_SEQ0EOC_Pos) |
|
||||
(((initStruct->EOC_IEn & ADC_SEQ1) ? 1 : 0) << ADC_IE_SEQ1EOC_Pos) |
|
||||
(((initStruct->EOC_IEn & ADC_SEQ2) ? 1 : 0) << ADC_IE_SEQ2EOC_Pos) |
|
||||
(((initStruct->EOC_IEn & ADC_SEQ3) ? 1 : 0) << ADC_IE_SEQ3EOC_Pos);
|
||||
|
||||
ADCx->IE |= (((initStruct->HalfIEn & ADC_SEQ0) ? 1 : 0) << ADC_IE_SEQ0HALF_Pos) |
|
||||
(((initStruct->HalfIEn & ADC_SEQ1) ? 1 : 0) << ADC_IE_SEQ1HALF_Pos) |
|
||||
(((initStruct->HalfIEn & ADC_SEQ2) ? 1 : 0) << ADC_IE_SEQ2HALF_Pos) |
|
||||
(((initStruct->HalfIEn & ADC_SEQ3) ? 1 : 0) << ADC_IE_SEQ3HALF_Pos);
|
||||
|
||||
switch((uint32_t)ADCx)
|
||||
{
|
||||
case ((uint32_t)ADC0):
|
||||
if(initStruct->EOC_IEn | initStruct->HalfIEn) NVIC_EnableIRQ(ADC0_IRQn);
|
||||
break;
|
||||
|
||||
case ((uint32_t)ADC1):
|
||||
if(initStruct->EOC_IEn | initStruct->HalfIEn) NVIC_EnableIRQ(ADC1_IRQn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t ADC_seq2pos(uint32_t seq)
|
||||
{
|
||||
uint32_t pos = 0;
|
||||
|
||||
switch(seq)
|
||||
{
|
||||
case ADC_SEQ0: pos = 0; break;
|
||||
case ADC_SEQ1: pos = 8; break;
|
||||
case ADC_SEQ2: pos = 16; break;
|
||||
case ADC_SEQ3: pos = 24; break;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_SEQ_Init()
|
||||
* 功能说明: ADC序列初始化
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的序列,有效值包括ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* ADC_SEQ_InitStructure * initStruct 包含ADC序列设定定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_SEQ_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_SEQ_InitStructure * initStruct)
|
||||
{
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
switch(seq)
|
||||
{
|
||||
case ADC_SEQ0:
|
||||
case ADC_SEQ1:
|
||||
ADCx->SEQCHN0 &= ~(0xFFFu << (pos * 2));
|
||||
ADCx->SEQCHN0 |= (initStruct->channels << (pos * 2));
|
||||
break;
|
||||
|
||||
case ADC_SEQ2:
|
||||
case ADC_SEQ3:
|
||||
ADCx->SEQCHN1 &= ~(0xFFFu << ((pos - 16) * 2));
|
||||
ADCx->SEQCHN1 |= (initStruct->channels << ((pos - 16) * 2));
|
||||
break;
|
||||
}
|
||||
|
||||
ADCx->SEQTRG &= ~(0xFFu << pos);
|
||||
ADCx->SEQTRG |= (initStruct->trig_src << pos);
|
||||
|
||||
ADCx->SEQCOV &= ~(0xFFu << pos);
|
||||
ADCx->SEQCOV |= ((initStruct->conv_cnt ? initStruct->conv_cnt - 1 : 0) << pos);
|
||||
|
||||
ADCx->SEQSMP &= ~(0x0Fu << (pos >> 1));
|
||||
ADCx->SEQSMP |= (initStruct->samp_tim << (pos >> 1));
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_CMP_Init()
|
||||
* 功能说明: ADC比较功能初始化
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的序列,有效值包括ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* ADC_CMP_InitStructure * initStruct 包含ADC比较功能设定定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_CMP_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_CMP_InitStructure * initStruct)
|
||||
{
|
||||
uint32_t idx;
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
idx = pos / 8;
|
||||
ADCx->SEQ[idx].CMP = (initStruct->UpperLimit << ADC_CMP_MAX_Pos) |
|
||||
(initStruct->LowerLimit << ADC_CMP_MIN_Pos);
|
||||
|
||||
if(initStruct->UpperLimitIEn) ADCx->IE |= (1 << (pos + 4));
|
||||
else ADCx->IE &= ~(1 << (pos + 4));
|
||||
|
||||
if(initStruct->LowerLimitIEn) ADCx->IE |= (1 << (pos + 5));
|
||||
else ADCx->IE &= ~(1 << (pos + 5));
|
||||
|
||||
if(initStruct->UpperLimitIEn || initStruct->LowerLimitIEn)
|
||||
{
|
||||
switch((uint32_t)ADCx)
|
||||
{
|
||||
case ((uint32_t)ADC0): NVIC_EnableIRQ(ADC0_IRQn); break;
|
||||
case ((uint32_t)ADC1): NVIC_EnableIRQ(ADC1_IRQn); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Open()
|
||||
* 功能说明: ADC开启,可以软件启动、或硬件触发ADC转换
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Open(ADC_TypeDef * ADCx)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
ADCx->CR2 |= (1 << ADC_CR2_ENLDO_Pos);
|
||||
for(i = 0; i < 64*20; i++) __NOP();
|
||||
|
||||
ADCx->CR |= (0x01 << ADC_CR_EN_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Calibrate()
|
||||
* 功能说明: ADC校准
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Calibrate(ADC_TypeDef * ADCx)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
ADCx->CALIB |= (1 << ADC_CALIB_RESET_Pos);
|
||||
for(i = 0; i < 120 * 20; i++) __NOP(); //2个采样时钟周期
|
||||
|
||||
ADCx->CALIB |= (1 << ADC_CALIB_START_Pos);
|
||||
for(i = 0; i < 120 * 10; i++) __NOP();
|
||||
ADCx->CALIB &=~(1 << ADC_CALIB_START_Pos);
|
||||
while(ADCx->CALIB & ADC_CALIB_BUSY_Msk) __NOP();
|
||||
|
||||
ADCx->CALIB |= (1 << ADC_CALIB_LOAD_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Close()
|
||||
* 功能说明: ADC关闭,无法软件启动、或硬件触发ADC转换
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Close(ADC_TypeDef * ADCx)
|
||||
{
|
||||
ADCx->CR &= ~(0x01 << ADC_CR_EN_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Start()
|
||||
* 功能说明: 软件触发模式下启动ADC转换
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合(即“按位或”运算)
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Start(ADC_TypeDef * ADCx, uint32_t seq)
|
||||
{
|
||||
ADCx->GO |= (seq << ADC_GO_SEQ0_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Stop()
|
||||
* 功能说明: 软件触发模式下停止ADC转换
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合(即“按位或”运算)
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_Stop(ADC_TypeDef * ADCx, uint32_t seq)
|
||||
{
|
||||
ADCx->GO &= ~(seq << ADC_GO_SEQ0_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_Read()
|
||||
* 功能说明: 从指定序列读取转换结果
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* uint32_t *chn 转换结果来自哪个通道,ADC_CH0、ADC_CH1、... ...、ADC_CH10、ADC_CH11
|
||||
* 输 出: uint32_t 读取到的转换结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t ADC_Read(ADC_TypeDef * ADCx, uint32_t seq, uint32_t *chn)
|
||||
{
|
||||
uint32_t idx = ADC_seq2pos(seq) / 8;
|
||||
|
||||
uint32_t reg = ADCx->SEQ[idx].DR;
|
||||
|
||||
*chn = 1 << ((reg & ADC_DR_CHNUM_Msk) >> ADC_DR_CHNUM_Pos);
|
||||
|
||||
return reg & ADC_DR_VALUE_Msk;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_DataAvailable()
|
||||
* 功能说明: 指定序列是否有数据可读取
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* 输 出: uint32_t 1 有数据可读取 0 无数据
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t ADC_DataAvailable(ADC_TypeDef * ADCx, uint32_t seq)
|
||||
{
|
||||
uint32_t idx = ADC_seq2pos(seq) / 8;
|
||||
|
||||
return (ADCx->SEQ[idx].SR & ADC_SR_EMPTY_Msk) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_INTEn()
|
||||
* 功能说明: 中断使能
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* uint32_t it interrupt type,有效值包括ADC_IT_EOC、ADC_IT_FIFO_OVF、ADC_IT_FIFO_HALF、ADC_IT_FIFO_FULL、
|
||||
* ADC_IT_CMP_MAX、ADC_IT_CMP_MIN 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
|
||||
{
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
ADCx->IE |= (it << pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_INTDis()
|
||||
* 功能说明: 中断禁止
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* uint32_t it interrupt type,有效值包括ADC_IT_EOC、ADC_IT_FIFO_OVF、ADC_IT_FIFO_HALF、ADC_IT_FIFO_FULL、
|
||||
* ADC_IT_CMP_MAX、ADC_IT_CMP_MIN 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_INTDis(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
|
||||
{
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
ADCx->IE &= ~(it << pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_INTClr()
|
||||
* 功能说明: 中断标志清除
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要设置的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* uint32_t it interrupt type,有效值包括ADC_IT_EOC、ADC_IT_FIFO_OVF、ADC_IT_FIFO_HALF、ADC_IT_FIFO_FULL、
|
||||
* ADC_IT_CMP_MAX、ADC_IT_CMP_MIN 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void ADC_INTClr(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
|
||||
{
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
ADCx->IF = (it << pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: ADC_INTStat()
|
||||
* 功能说明: 中断状态查询
|
||||
* 输 入: ADC_TypeDef * ADCx 指定要设置的ADC,有效值包括ADC0、ADC1
|
||||
* uint32_t seq 指定要查询的ADC序列,有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3
|
||||
* uint32_t it interrupt type,有效值包括ADC_IT_EOC、ADC_IT_FIFO_OVF、ADC_IT_FIFO_HALF、ADC_IT_FIFO_FULL、
|
||||
* ADC_IT_CMP_MAX、ADC_IT_CMP_MIN 及其“或”
|
||||
* 输 出: uint32_t 1 中断发生 0 中断未发生
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t ADC_INTStat(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it)
|
||||
{
|
||||
uint32_t pos = ADC_seq2pos(seq);
|
||||
|
||||
return (ADCx->IF & (it << pos)) ? 1 : 0;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#ifndef __SWM341_ADC_H__
|
||||
#define __SWM341_ADC_H__
|
||||
|
||||
typedef struct {
|
||||
uint8_t clk_src; //ADC转换时钟源:ADC_CLKSRC_HRC、ADC_CLKSRC_XTAL、...
|
||||
uint8_t samplAvg; //采样取平均,触发启动ADC转换后,ADC在一个通道上连续采样、转换多次,并将它们的平均值作为该通道转换结果
|
||||
|
||||
uint8_t EOC_IEn; //EOC中断使能, 可针对每个序列设置,其有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合(即“按位或”运算)
|
||||
uint8_t HalfIEn; //FIFO半满中断使能,可针对每个序列设置,其有效值为ADC_SEQ0、ADC_SEQ1、ADC_SEQ2、ADC_SEQ3及其组合(即“按位或”运算)
|
||||
} ADC_InitStructure;
|
||||
|
||||
typedef struct {
|
||||
uint16_t channels; //ADC序列转换通道选中,ADC_CH0、ADC_CH1、... ... 、ADC_CH7及其组合(即“按位或”运算)
|
||||
uint8_t trig_src; //ADC序列触发方式:ADC_TRIGGER_SW、ADC_TRIGGER_TIMER2、ADC_TRIGGER_TIMER3、... ...
|
||||
uint16_t conv_cnt; //ADC序列转换次数,可取值1--256
|
||||
uint8_t samp_tim; //ADC序列采样时间,可取值ADC_SAMPLE_1CLOCK、ADC_SAMPLE_2CLOCK、ADC_SAMPLE_4CLOCK、ADC_SAMPLE_8CLOCK
|
||||
} ADC_SEQ_InitStructure;
|
||||
|
||||
typedef struct {
|
||||
uint16_t UpperLimit; //比较上限值
|
||||
uint16_t UpperLimitIEn; //ADC转换结果大于UpperLimit中断使能
|
||||
uint16_t LowerLimit; //比较下限值
|
||||
uint16_t LowerLimitIEn; //ADC转换结果小于LowerLimit中断使能
|
||||
} ADC_CMP_InitStructure;
|
||||
|
||||
#define ADC_CH0 0x001
|
||||
#define ADC_CH1 0x002
|
||||
#define ADC_CH2 0x004
|
||||
#define ADC_CH3 0x008
|
||||
#define ADC_CH4 0x010
|
||||
#define ADC_CH5 0x020
|
||||
#define ADC_CH6 0x040
|
||||
#define ADC_CH7 0x080
|
||||
#define ADC_CH8 0x100
|
||||
#define ADC_CH9 0x200
|
||||
#define ADC_CH10 0x400
|
||||
#define ADC_CH11 0x800
|
||||
|
||||
#define ADC_SEQ0 0x1
|
||||
#define ADC_SEQ1 0x2
|
||||
#define ADC_SEQ2 0x4
|
||||
#define ADC_SEQ3 0x8
|
||||
|
||||
#define ADC_CLKSRC_HRC ((0 << 2) | 0)
|
||||
#define ADC_CLKSRC_XTAL ((0 << 2) | 1)
|
||||
#define ADC_CLKSRC_PLL ((0 << 2) | 2)
|
||||
#define ADC_CLKSRC_HRC_DIV4 ((2 << 2) | 0)
|
||||
#define ADC_CLKSRC_XTAL_DIV4 ((2 << 2) | 1)
|
||||
#define ADC_CLKSRC_PLL_DIV4 ((2 << 2) | 2)
|
||||
#define ADC_CLKSRC_HRC_DIV8 ((3 << 2) | 0)
|
||||
#define ADC_CLKSRC_XTAL_DIV8 ((3 << 2) | 1)
|
||||
#define ADC_CLKSRC_PLL_DIV8 ((3 << 2) | 2)
|
||||
|
||||
#define ADC_AVG_SAMPLE1 0
|
||||
#define ADC_AVG_SAMPLE2 1 //一次启动连续采样、转换2次,并计算两次结果的平均值作为转换结果
|
||||
#define ADC_AVG_SAMPLE4 2
|
||||
#define ADC_AVG_SAMPLE8 3
|
||||
|
||||
#define ADC_TRIGGER_NO 0
|
||||
#define ADC_TRIGGER_SW 1 //软件启动
|
||||
#define ADC_TRIGGER_TIMER2 2
|
||||
#define ADC_TRIGGER_TIMER3 3
|
||||
#define ADC_TRIGGER_EXTRIG0 4
|
||||
#define ADC_TRIGGER_EXTRIG1 5
|
||||
#define ADC_TRIGGER_PWM0 0x10
|
||||
#define ADC_TRIGGER_PWM1 0x11
|
||||
#define ADC_TRIGGER_PWM2 0x12
|
||||
#define ADC_TRIGGER_PWM3 0x13
|
||||
#define ADC_TRIGGER_PWM4 0x14
|
||||
|
||||
#define ADC_SAMPLE_1CLOCK 0
|
||||
#define ADC_SAMPLE_2CLOCK 1
|
||||
#define ADC_SAMPLE_4CLOCK 2
|
||||
#define ADC_SAMPLE_8CLOCK 3
|
||||
#define ADC_SAMPLE_16CLOCK 4
|
||||
#define ADC_SAMPLE_32CLOCK 5
|
||||
#define ADC_SAMPLE_64CLOCK 6
|
||||
#define ADC_SAMPLE_128CLOCK 7
|
||||
|
||||
|
||||
/* Interrupt Type */
|
||||
#define ADC_IT_EOC (1 << 0) //End Of Conversion
|
||||
#define ADC_IT_FIFO_OVF (1 << 1) //FIFO Overflow
|
||||
#define ADC_IT_FIFO_HALF (1 << 2) //FIFO Half Full
|
||||
#define ADC_IT_FIFO_FULL (1 << 3) //FIFO Full
|
||||
#define ADC_IT_CMP_MAX (1 << 4) //转换结果大于COMP.MAX
|
||||
#define ADC_IT_CMP_MIN (1 << 5) //转换结果小于COMP.MIN
|
||||
|
||||
|
||||
void ADC_Init(ADC_TypeDef * ADCx, ADC_InitStructure * initStruct); //ADC模数转换器初始化
|
||||
void ADC_SEQ_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_SEQ_InitStructure * initStruct); //ADC序列初始化
|
||||
void ADC_CMP_Init(ADC_TypeDef * ADCx, uint32_t seq, ADC_CMP_InitStructure * initStruct); //ADC比较功能初始化
|
||||
void ADC_Open(ADC_TypeDef * ADCx); //ADC开启,可以软件启动、或硬件触发ADC转换
|
||||
void ADC_Calibrate(ADC_TypeDef * ADCx); //ADC校准
|
||||
void ADC_Close(ADC_TypeDef * ADCx); //ADC关闭,无法软件启动、或硬件触发ADC转换
|
||||
void ADC_Start(ADC_TypeDef * ADCx, uint32_t seq); //启动指定ADC,开始模数转换
|
||||
void ADC_Stop(ADC_TypeDef * ADCx, uint32_t seq); //关闭指定ADC,停止模数转换
|
||||
|
||||
uint32_t ADC_Read(ADC_TypeDef * ADCx, uint32_t seq, uint32_t *chn); //从指定通道读取转换结果
|
||||
uint32_t ADC_DataAvailable(ADC_TypeDef * ADCx, uint32_t seq); //指定序列是否有数据可读取
|
||||
|
||||
|
||||
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
|
||||
void ADC_INTEn(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
|
||||
void ADC_INTClr(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
|
||||
uint32_t ADC_INTStat(ADC_TypeDef * ADCx, uint32_t seq, uint32_t it);
|
||||
|
||||
|
||||
#endif //__SWM341_ADC_H__
|
||||
@@ -0,0 +1,442 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_can.c
|
||||
* 功能说明: SWM341单片机的CAN模块驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.1.0 2017年10月25日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_can.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_Init()
|
||||
* 功能说明: CAN接口初始化
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* CAN_InitStructure * initStruct 包含CAN接口相关设定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_Init(CAN_TypeDef * CANx, CAN_InitStructure * initStruct)
|
||||
{
|
||||
uint32_t brp = (SystemCoreClock/2)/2/initStruct->Baudrate/(1 + (initStruct->CAN_bs1 + 1) + (initStruct->CAN_bs2 + 1)) - 1;
|
||||
|
||||
switch((uint32_t)CANx)
|
||||
{
|
||||
case ((uint32_t)CAN0):
|
||||
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CAN0_Pos);
|
||||
break;
|
||||
|
||||
case ((uint32_t)CAN1):
|
||||
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_CAN1_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
CAN_Close(CANx); //一些关键寄存器只能在CAN关闭时设置
|
||||
|
||||
CANx->CR &= ~(CAN_CR_LOM_Msk | CAN_CR_STM_Msk);
|
||||
CANx->CR |= (initStruct->Mode << CAN_CR_LOM_Pos);
|
||||
|
||||
CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
|
||||
(initStruct->CAN_bs1 << CAN_BT1_TSEG1_Pos) |
|
||||
(initStruct->CAN_bs2 << CAN_BT1_TSEG2_Pos);
|
||||
|
||||
CANx->BT0 = (initStruct->CAN_sjw << CAN_BT0_SJW_Pos) |
|
||||
((brp & 0x3F) << CAN_BT0_BRP_Pos);
|
||||
|
||||
CANx->BT2 = ((brp >> 6) << CAN_BT2_BRP_Pos);
|
||||
|
||||
CANx->RXERR = 0; //只能在复位模式下清除
|
||||
CANx->TXERR = 0;
|
||||
|
||||
CANx->IE = (initStruct->RXNotEmptyIEn << CAN_IE_RXDA_Pos) |
|
||||
(initStruct->ArbitrLostIEn << CAN_IE_ARBLOST_Pos) |
|
||||
(initStruct->ErrPassiveIEn << CAN_IE_ERRPASS_Pos);
|
||||
|
||||
switch((uint32_t)CANx)
|
||||
{
|
||||
case ((uint32_t)CAN0):
|
||||
if(initStruct->RXNotEmptyIEn | initStruct->ArbitrLostIEn | initStruct->ErrPassiveIEn)
|
||||
{
|
||||
NVIC_EnableIRQ(CAN0_IRQn);
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ(CAN0_IRQn);
|
||||
}
|
||||
break;
|
||||
|
||||
case ((uint32_t)CAN1):
|
||||
if(initStruct->RXNotEmptyIEn | initStruct->ArbitrLostIEn | initStruct->ErrPassiveIEn)
|
||||
{
|
||||
NVIC_EnableIRQ(CAN1_IRQn);
|
||||
}
|
||||
else
|
||||
{
|
||||
NVIC_DisableIRQ(CAN1_IRQn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_Open()
|
||||
* 功能说明: CAN接口打开
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_Open(CAN_TypeDef * CANx)
|
||||
{
|
||||
CANx->CR &= ~(0x01 << CAN_CR_RST_Pos); //退出复位模式,进入工作模式
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_Close()
|
||||
* 功能说明: CAN接口关闭
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_Close(CAN_TypeDef * CANx)
|
||||
{
|
||||
CANx->CR |= (0x01 << CAN_CR_RST_Pos); //进入复位模式,不能发送和接收数据
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_Transmit()
|
||||
* 功能说明: CAN发送数据
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t format CAN_FRAME_STD 标准帧 CAN_FRAME_EXT 扩展帧
|
||||
* uint32_t id 消息ID
|
||||
* uint8_t data[] 要发送的数据
|
||||
* uint32_t size 要发送的数据的个数
|
||||
* uint32_t once 只发送一次,即使发送失败(仲裁丢失、发送出错、NAK)也不尝试重发
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_Transmit(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint8_t data[], uint32_t size, uint32_t once)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if(format == CAN_FRAME_STD)
|
||||
{
|
||||
CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
|
||||
(0 << CAN_INFO_RTR_Pos) |
|
||||
(size << CAN_INFO_DLC_Pos);
|
||||
|
||||
CANx->FRAME.DATA[0] = id >> 3;
|
||||
CANx->FRAME.DATA[1] = id << 5;
|
||||
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
CANx->FRAME.DATA[i+2] = data[i];
|
||||
}
|
||||
}
|
||||
else //if(format == CAN_FRAME_EXT)
|
||||
{
|
||||
CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
|
||||
(0 << CAN_INFO_RTR_Pos) |
|
||||
(size << CAN_INFO_DLC_Pos);
|
||||
|
||||
CANx->FRAME.DATA[0] = id >> 21;
|
||||
CANx->FRAME.DATA[1] = id >> 13;
|
||||
CANx->FRAME.DATA[2] = id >> 5;
|
||||
CANx->FRAME.DATA[3] = id << 3;
|
||||
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
CANx->FRAME.DATA[i+4] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(CANx->CR & CAN_CR_STM_Msk)
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_SRR_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(once == 0)
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos) | (1 << CAN_CMD_ABTTX_Pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_TransmitRequest()
|
||||
* 功能说明: CAN发送远程请求,请求远程节点发送数据
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t format CAN_FRAME_STD 标准帧 CAN_FRAME_EXT 扩展帧
|
||||
* uint32_t id 消息ID
|
||||
* uint32_t once 只发送一次,即使发送失败(仲裁丢失、发送出错、NAK)也不尝试重发
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_TransmitRequest(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint32_t once)
|
||||
{
|
||||
if(format == CAN_FRAME_STD)
|
||||
{
|
||||
CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
|
||||
(1 << CAN_INFO_RTR_Pos) |
|
||||
(0 << CAN_INFO_DLC_Pos);
|
||||
|
||||
CANx->FRAME.DATA[0] = id >> 3;
|
||||
CANx->FRAME.DATA[1] = id << 5;
|
||||
}
|
||||
else //if(format == CAN_FRAME_EXT)
|
||||
{
|
||||
CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
|
||||
(1 << CAN_INFO_RTR_Pos) |
|
||||
(0 << CAN_INFO_DLC_Pos);
|
||||
|
||||
CANx->FRAME.DATA[0] = id >> 21;
|
||||
CANx->FRAME.DATA[1] = id >> 13;
|
||||
CANx->FRAME.DATA[2] = id >> 5;
|
||||
CANx->FRAME.DATA[3] = id << 3;
|
||||
}
|
||||
|
||||
if(once == 0)
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_TXREQ_Pos) | (1 << CAN_CMD_ABTTX_Pos);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_Receive()
|
||||
* 功能说明: CAN接收数据
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* CAN_RXMessage *msg 接收到的消息存储在此结构体变量中
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_Receive(CAN_TypeDef * CANx, CAN_RXMessage *msg)
|
||||
{
|
||||
uint32_t i;
|
||||
msg->format = (CANx->FRAME.INFO & CAN_INFO_FF_Msk) >> CAN_INFO_FF_Pos;
|
||||
|
||||
msg->remote = (CANx->FRAME.INFO & CAN_INFO_RTR_Msk) >> CAN_INFO_RTR_Pos;
|
||||
msg->size = (CANx->FRAME.INFO & CAN_INFO_DLC_Msk) >> CAN_INFO_DLC_Pos;
|
||||
|
||||
if(msg->format == CAN_FRAME_STD)
|
||||
{
|
||||
msg->id = (CANx->FRAME.DATA[0] << 3) | (CANx->FRAME.DATA[1] >> 5);
|
||||
|
||||
for(i = 0; i < msg->size; i++)
|
||||
{
|
||||
msg->data[i] = CANx->FRAME.DATA[i+2];
|
||||
}
|
||||
}
|
||||
else //if(msg->format == CAN_FRAME_EXT)
|
||||
{
|
||||
msg->id = (CANx->FRAME.DATA[0] << 21) | (CANx->FRAME.DATA[1] << 13) | (CANx->FRAME.DATA[2] << 5) | (CANx->FRAME.DATA[3] >> 3);
|
||||
|
||||
for(i = 0; i < msg->size; i++)
|
||||
{
|
||||
msg->data[i] = CANx->FRAME.DATA[i+4];
|
||||
}
|
||||
}
|
||||
|
||||
CANx->CMD = (1 << CAN_CMD_RRB_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_TXComplete()
|
||||
* 功能说明: 发送是否完成
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: uint32_t 1 已经完成 0 还未完成
|
||||
* 注意事项: 发送被Abort也会触发发送完成,但不会触发发送成功
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t CAN_TXComplete(CAN_TypeDef * CANx)
|
||||
{
|
||||
return (CANx->SR & CAN_SR_TXBR_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_TXSuccess()
|
||||
* 功能说明: 发送是否成功
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: uint32_t 1 发送成功 0 发送失败
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t CAN_TXSuccess(CAN_TypeDef * CANx)
|
||||
{
|
||||
return (CANx->SR & CAN_SR_TXOK_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_AbortTransmit()
|
||||
* 功能说明: 终止发送
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: 无
|
||||
* 注意事项: 正在进行的发送无法终止,但执行此命令后若发送失败不会再重发
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_AbortTransmit(CAN_TypeDef * CANx)
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_ABTTX_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_TXBufferReady()
|
||||
* 功能说明: TX Buffer是否准备好可以写入消息
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: uint32_t 1 已准备好 0 未准备好
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t CAN_TXBufferReady(CAN_TypeDef * CANx)
|
||||
{
|
||||
return (CANx->SR & CAN_SR_TXBR_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_RXDataAvailable()
|
||||
* 功能说明: RX FIFO中是否有数据可读出
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: uint32_t 1 有数据可读出 0 没有数据
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t CAN_RXDataAvailable(CAN_TypeDef * CANx)
|
||||
{
|
||||
return (CANx->SR & CAN_SR_RXDA_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_SetBaudrate()
|
||||
* 功能说明: 设置波特率
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t baudrate 波特率,即位传输速率
|
||||
* uint32_t CAN_bs1 CAN_BS1_1tq、CAN_BS1_2tq、... ... 、CAN_BS1_16tq
|
||||
* uint32_t CAN_bs2 CAN_BS2_1tq、CAN_BS2_2tq、... ... 、CAN_BS2_8tq
|
||||
* uint32_t CAN_sjw CAN_SJW_1tq、CAN_SJW_2tq、CAN_SJW_3tq、CAN_SJW_4tq
|
||||
* 输 出: 无
|
||||
* 注意事项: 设置前需要先调用CAN_Close()关闭CAN模块
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_SetBaudrate(CAN_TypeDef * CANx, uint32_t baudrate, uint32_t CAN_bs1, uint32_t CAN_bs2, uint32_t CAN_sjw)
|
||||
{
|
||||
uint32_t brp = (SystemCoreClock/2)/2/baudrate/(1 + (CAN_bs1 + 1) + (CAN_bs2 + 1)) - 1;
|
||||
|
||||
CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
|
||||
(CAN_bs1 << CAN_BT1_TSEG1_Pos) |
|
||||
(CAN_bs2 << CAN_BT1_TSEG2_Pos);
|
||||
|
||||
CANx->BT0 = (CAN_sjw << CAN_BT0_SJW_Pos) |
|
||||
((brp & 0x3F) << CAN_BT0_BRP_Pos);
|
||||
|
||||
CANx->BT2 = ((brp >> 6) << CAN_BT2_BRP_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_SetFilter32b()
|
||||
* 功能说明: 设置接收滤波器,模式为1个32位滤波器
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t filter 要设置的滤波器,有效值有CAN_FILTER_1、CAN_FILTER_2、...、CAN_FILTER_16
|
||||
* uint32_t check 与mask一起决定了接收到的Message是否是自己需要的:check & mask == ID & mask的Message通过过滤
|
||||
* uint32_t mask
|
||||
* 输 出: 无
|
||||
* 注意事项: 只能在关闭时设置
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_SetFilter32b(CAN_TypeDef * CANx, uint32_t filter, uint32_t check, uint32_t mask)
|
||||
{
|
||||
CANx->AFM |= (1 << filter);
|
||||
|
||||
CANx->ACR[filter] = __REV(check << 3); // 高29位
|
||||
CANx->AMR[filter] = __REV(~(mask << 3));
|
||||
|
||||
CANx->AFE |= (1 << filter);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_SetFilter16b()
|
||||
* 功能说明: 设置接收滤波器,模式为2个16位滤波器
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t filter 要设置的滤波器,有效值有CAN_FILTER_1、CAN_FILTER_2、...、CAN_FILTER_16
|
||||
* uint16_t check1 与mask一起决定了接收到的Message是否是自己需要的:check & mask == ID & mask的Message通过过滤
|
||||
* uint16_t mask1
|
||||
* uint16_t check2
|
||||
* uint16_t mask2
|
||||
* 输 出: 无
|
||||
* 注意事项: 只能在关闭时设置
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint16_t mask1, uint16_t check2, uint16_t mask2)
|
||||
{
|
||||
CANx->AFM &= ~(1 << filter);
|
||||
|
||||
CANx->ACR[filter] = __REV((check1 << 5) | (check2 << 21)); // 高11位
|
||||
CANx->AMR[filter] = __REV(~((mask1 << 5) | (mask2 << 21)));
|
||||
|
||||
CANx->AFE |= (1 << filter);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_INTEn()
|
||||
* 功能说明: 使能指定中断
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t it interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
|
||||
* CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it)
|
||||
{
|
||||
CANx->IE |= it;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_INTDis()
|
||||
* 功能说明: 关闭指定中断
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t it interrupt type,有效值包括 CAN_IT_RX_NOTEMPTY、CAN_IT_RX_OVERFLOW、CAN_IT_TX_EMPTY、CAN_IT_ARBLOST、
|
||||
* CAN_IT_ERR、CAN_IT_ERR_WARN、CAN_IT_ERR_PASS、CAN_IT_WAKEUP 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it)
|
||||
{
|
||||
CANx->IE &= ~it;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_INTClr()
|
||||
* 功能说明: 清除中断标志
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* uint32_t it interrupt type,有效值包括 CAN_IT_RX_OVERFLOW
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it)
|
||||
{
|
||||
CANx->CMD = (1 << CAN_CMD_CLROV_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CAN_INTStat()
|
||||
* 功能说明: 查询中断状态
|
||||
* 输 入: CAN_TypeDef * CANx 指定要被设置的CAN接口,有效值包括CAN0、CAN1
|
||||
* 输 出: uint32_t 当前中断状态
|
||||
* 注意事项: CANx->IF读取清零,因此在中断ISR中只能读取一次,不能多次读取
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t CAN_INTStat(CAN_TypeDef * CANx)
|
||||
{
|
||||
return CANx->IF;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef __SWM341_CAN_H__
|
||||
#define __SWM341_CAN_H__
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t Mode; //CAN_MODE_NORMAL、CAN_MODE_LISTEN、CAN_MODE_SELFTEST
|
||||
uint8_t CAN_bs1; //CAN_BS1_1tq、CAN_BS1_2tq、... ... 、CAN_BS1_16tq
|
||||
uint8_t CAN_bs2; //CAN_BS2_1tq、CAN_BS2_2tq、... ... 、CAN_BS2_8tq
|
||||
uint8_t CAN_sjw; //CAN_SJW_1tq、CAN_SJW_2tq、CAN_SJW_3tq、CAN_SJW_4tq
|
||||
uint32_t Baudrate; //波特率,即位传输速率,取值1--1000000
|
||||
uint8_t RXNotEmptyIEn; //接收FIFO非空,有数据可读
|
||||
uint8_t ArbitrLostIEn; //控制器丢失仲裁变成接收方
|
||||
uint8_t ErrPassiveIEn; //接收/发送错误计数值达到127
|
||||
} CAN_InitStructure;
|
||||
|
||||
|
||||
#define CAN_MODE_NORMAL 0 //常规模式
|
||||
#define CAN_MODE_LISTEN 1 //监听模式
|
||||
#define CAN_MODE_SELFTEST 2 //自测模式
|
||||
|
||||
#define CAN_BS1_1tq 0
|
||||
#define CAN_BS1_2tq 1
|
||||
#define CAN_BS1_3tq 2
|
||||
#define CAN_BS1_4tq 3
|
||||
#define CAN_BS1_5tq 4
|
||||
#define CAN_BS1_6tq 5
|
||||
#define CAN_BS1_7tq 6
|
||||
#define CAN_BS1_8tq 7
|
||||
#define CAN_BS1_9tq 8
|
||||
#define CAN_BS1_10tq 9
|
||||
#define CAN_BS1_11tq 10
|
||||
#define CAN_BS1_12tq 11
|
||||
#define CAN_BS1_13tq 12
|
||||
#define CAN_BS1_14tq 13
|
||||
#define CAN_BS1_15tq 14
|
||||
#define CAN_BS1_16tq 15
|
||||
|
||||
#define CAN_BS2_1tq 0
|
||||
#define CAN_BS2_2tq 1
|
||||
#define CAN_BS2_3tq 2
|
||||
#define CAN_BS2_4tq 3
|
||||
#define CAN_BS2_5tq 4
|
||||
#define CAN_BS2_6tq 5
|
||||
#define CAN_BS2_7tq 6
|
||||
#define CAN_BS2_8tq 7
|
||||
|
||||
#define CAN_SJW_1tq 0
|
||||
#define CAN_SJW_2tq 1
|
||||
#define CAN_SJW_3tq 2
|
||||
#define CAN_SJW_4tq 3
|
||||
|
||||
#define CAN_FRAME_STD 0
|
||||
#define CAN_FRAME_EXT 1
|
||||
|
||||
#define CAN_FILTER_1 0
|
||||
#define CAN_FILTER_2 1
|
||||
#define CAN_FILTER_3 2
|
||||
#define CAN_FILTER_4 3
|
||||
#define CAN_FILTER_5 4
|
||||
#define CAN_FILTER_6 5
|
||||
#define CAN_FILTER_7 6
|
||||
#define CAN_FILTER_8 7
|
||||
#define CAN_FILTER_9 8
|
||||
#define CAN_FILTER_10 9
|
||||
#define CAN_FILTER_11 10
|
||||
#define CAN_FILTER_12 11
|
||||
#define CAN_FILTER_13 12
|
||||
#define CAN_FILTER_14 13
|
||||
#define CAN_FILTER_15 14
|
||||
#define CAN_FILTER_16 15
|
||||
|
||||
|
||||
/* Interrupt Type */
|
||||
#define CAN_IT_RX_NOTEMPTY (0x01 << 0) //RX Buffer Not Empty
|
||||
#define CAN_IT_RX_OVERFLOW (0x01 << 3) //RX Buffer Overflow
|
||||
#define CAN_IT_TX_EMPTY (0x01 << 1) //TX Buffer Empty
|
||||
#define CAN_IT_ARBLOST (0x01 << 6) //Arbitration lost
|
||||
#define CAN_IT_ERR (0x01 << 7)
|
||||
#define CAN_IT_ERR_WARN (0x01 << 2) //TXERR/RXERR计数值达到Error Warning Limit
|
||||
#define CAN_IT_ERR_PASS (0x01 << 5) //TXERR/RXERR计数值达到127
|
||||
#define CAN_IT_WAKEUP (0x01 << 4)
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t id; //消息ID
|
||||
uint8_t format; //帧格式:CAN_FRAME_STD、CAN_FRAME_EXT
|
||||
uint8_t remote; //消息是否为远程帧
|
||||
uint8_t size; //接收到的数据个数
|
||||
uint8_t data[8]; //接收到的数据
|
||||
} CAN_RXMessage;
|
||||
|
||||
|
||||
void CAN_Init(CAN_TypeDef * CANx, CAN_InitStructure * initStruct);
|
||||
void CAN_Open(CAN_TypeDef * CANx);
|
||||
void CAN_Close(CAN_TypeDef * CANx);
|
||||
|
||||
void CAN_Transmit(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint8_t data[], uint32_t size, uint32_t once);
|
||||
void CAN_TransmitRequest(CAN_TypeDef * CANx, uint32_t format, uint32_t id, uint32_t once);
|
||||
void CAN_Receive(CAN_TypeDef * CANx, CAN_RXMessage *msg);
|
||||
|
||||
uint32_t CAN_TXComplete(CAN_TypeDef * CANx);
|
||||
uint32_t CAN_TXSuccess(CAN_TypeDef * CANx);
|
||||
|
||||
void CAN_AbortTransmit(CAN_TypeDef * CANx);
|
||||
|
||||
uint32_t CAN_TXBufferReady(CAN_TypeDef * CANx);
|
||||
uint32_t CAN_RXDataAvailable(CAN_TypeDef * CANx);
|
||||
|
||||
void CAN_SetBaudrate(CAN_TypeDef * CANx, uint32_t baudrate, uint32_t CAN_bs1, uint32_t CAN_bs2, uint32_t CAN_sjw);
|
||||
|
||||
void CAN_SetFilter32b(CAN_TypeDef * CANx, uint32_t filter, uint32_t check, uint32_t mask);
|
||||
void CAN_SetFilter16b(CAN_TypeDef * CANx, uint32_t filter, uint16_t check1, uint16_t mask1, uint16_t check2, uint16_t mask2);
|
||||
|
||||
void CAN_INTEn(CAN_TypeDef * CANx, uint32_t it);
|
||||
void CAN_INTDis(CAN_TypeDef * CANx, uint32_t it);
|
||||
void CAN_INTClr(CAN_TypeDef * CANx, uint32_t it);
|
||||
uint32_t CAN_INTStat(CAN_TypeDef * CANx);
|
||||
|
||||
|
||||
#endif //__SWM341_CAN_H__
|
||||
@@ -0,0 +1,40 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_cordic.c
|
||||
* 功能说明: SWM341单片机的CORDIC功能驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.0.0 2016年1月30日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_cordic.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Init()
|
||||
* 功能说明: CORDIC初始化
|
||||
* 输 入: CORDIC_TypeDef * CORDICx 指定要被设置的CORDIC,有效值包括CORDIC
|
||||
* 输 出: 无
|
||||
* 注意事项: CORDIC模块依赖DIV模块,因为CORDIC_Arctan()要使用硬件除法模块计算参数值
|
||||
******************************************************************************************************************************************/
|
||||
void CORDIC_Init(CORDIC_TypeDef * CORDICx)
|
||||
{
|
||||
switch((uint32_t)CORDICx)
|
||||
{
|
||||
case ((uint32_t)CORDIC):
|
||||
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CORDIC_Pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
#ifndef __SWM341_CORDIC_H__
|
||||
#define __SWM341_CORDIC_H__
|
||||
|
||||
#define CORDIC_PI 3.141592653589793
|
||||
|
||||
void CORDIC_Init(CORDIC_TypeDef * CORDICx);
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Sin()
|
||||
* 功能说明: 使用CORDIC模块计算sin
|
||||
* 输 入: uint32_t radian 要计算sin值的角度,以弧度为单位,取值范围0.01~1.56;但需要将弧度值乘以16384作为参数调用此函数
|
||||
* 输 出: 无
|
||||
* 注意事项: 需要将弧度值乘以16384作为参数调用此函数
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CORDIC_Sin(uint32_t radian)
|
||||
{
|
||||
CORDIC->INPUT = radian;
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (1 << CORDIC_CMD_SINCOS_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Sin_IsDone()
|
||||
* 功能说明: CORDIC模块sin运算是否完成
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 sin运算未完成 1 sin运算已完成,可取出运算结果
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Sin_IsDone(void)
|
||||
{
|
||||
return (CORDIC->SIN & CORDIC_SIN_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Sin_Result()
|
||||
* 功能说明: 取出CORDIC模块sin运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t sin运算结果,Result[15:14]表示整数部分,Result[13:0]表示小数部分
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Sin_Result(void)
|
||||
{
|
||||
return CORDIC->SIN & (CORDIC_SIN_F_Msk | CORDIC_SIN_I_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Cos()
|
||||
* 功能说明: 使用CORDIC模块计算cos
|
||||
* 输 入: uint32_t radian 要计算cos值的角度,以弧度为单位,取值范围0.01~1.56;但需要将弧度值乘以16384作为参数调用此函数
|
||||
* 输 出: 无
|
||||
* 注意事项: 需要将弧度值乘以16384作为参数调用此函数
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CORDIC_Cos(uint32_t radian)
|
||||
{
|
||||
CORDIC->INPUT = radian;
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (1 << CORDIC_CMD_SINCOS_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Cos_IsDone()
|
||||
* 功能说明: CORDIC模块cos运算是否完成
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 cos运算未完成 1 cos运算已完成,可取出运算结果
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Cos_IsDone(void)
|
||||
{
|
||||
return (CORDIC->COS & CORDIC_COS_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Cos_Result()
|
||||
* 功能说明: 取出CORDIC模块cos运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t cos运算结果,Result[15:14]表示整数部分,Result[13:0]表示小数部分
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Cos_Result(void)
|
||||
{
|
||||
return CORDIC->COS & (CORDIC_COS_F_Msk | CORDIC_COS_I_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Arctan()
|
||||
* 功能说明: 使用CORDIC模块计算arctan
|
||||
* 输 入: uint32_t input 取值范围0.05~10000,但需要将其乘以16384作为参数调用此函数
|
||||
* 输 出: 无
|
||||
* 注意事项: 需要将待计算值乘以16384作为参数调用此函数
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CORDIC_Arctan(uint32_t input)
|
||||
{
|
||||
if((input > 819) && (input <= 8192))
|
||||
{
|
||||
CORDIC->INPUT = input * 2;
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (0 << CORDIC_CMD_RANGE_Pos);
|
||||
}
|
||||
else if((input > 8192) && (input <= 32768))
|
||||
{
|
||||
CORDIC->INPUT = input;
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (1 << CORDIC_CMD_RANGE_Pos);
|
||||
}
|
||||
else if((input > 32768) && (input < 10000*16384))
|
||||
{
|
||||
CORDIC->INPUT = 32768*16384/input;
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (0 << CORDIC_CMD_SINCOS_Pos) | (2 << CORDIC_CMD_RANGE_Pos);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Arctan_IsDone()
|
||||
* 功能说明: CORDIC模块arctan运算是否完成
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 arctan运算未完成 1 arctan运算已完成,可取出运算结果
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Arctan_IsDone(void)
|
||||
{
|
||||
return (CORDIC->ARCTAN & CORDIC_ARCTAN_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Arctan_Result()
|
||||
* 功能说明: 取出CORDIC模块arctan运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t arctan运算结果,为弧度值,Result[15:14]表示整数部分,Result[13:0]表示小数部分
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Arctan_Result(void)
|
||||
{
|
||||
return CORDIC->ARCTAN & (CORDIC_ARCTAN_F_Msk | CORDIC_ARCTAN_I_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Mul()
|
||||
* 功能说明: 使用CORDIC模块计算乘法
|
||||
* 输 入: uint16_t mul1 乘数1
|
||||
* uint16_t mul2 乘数2
|
||||
* 输 出: 无
|
||||
* 注意事项: 需要将乘数乘以16384作为参数调用此函数
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CORDIC_Mul(uint16_t mul1, uint16_t mul2)
|
||||
{
|
||||
CORDIC->INPUT = mul1 | (mul2 << 16);
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (3 << CORDIC_CMD_MULDIV_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Mul_IsDone()
|
||||
* 功能说明: CORDIC模块乘法运算是否完成
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 乘法运算未完成 1 乘法运算已完成,可取出运算结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Mul_IsDone(void)
|
||||
{
|
||||
return (CORDIC->SIN & CORDIC_SIN_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Mul_Result()
|
||||
* 功能说明: 取出CORDIC模块乘法运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 乘法运算结果,Result[15:14]表示整数部分,Result[13:0]表示小数部分
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Mul_Result(void)
|
||||
{
|
||||
return CORDIC->SIN & (CORDIC_SIN_F_Msk | CORDIC_SIN_I_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Div()
|
||||
* 功能说明: 使用CORDIC模块计算除法
|
||||
* 输 入: uint16_t dividend 被除数
|
||||
* uint16_t divisor 除数
|
||||
* 输 出: 无
|
||||
* 注意事项: 需要将除数和被除数值乘以16384作为参数调用此函数
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CORDIC_Div(uint16_t dividend, uint16_t divisor)
|
||||
{
|
||||
CORDIC->INPUT = divisor | (dividend << 16);
|
||||
|
||||
CORDIC->CMD = (1 << CORDIC_CMD_START_Pos) | (2 << CORDIC_CMD_MULDIV_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Div_IsDone()
|
||||
* 功能说明: CORDIC模块除法运算是否完成
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 除法运算未完成 1 除法运算已完成,可取出运算结果
|
||||
* 注意事项:
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Div_IsDone(void)
|
||||
{
|
||||
return (CORDIC->ARCTAN & CORDIC_ARCTAN_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CORDIC_Div_Result()
|
||||
* 功能说明: 取出CORDIC模块除法运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 除法运算结果,为弧度值,Result[15:14]表示整数部分,Result[13:0]表示小数部分
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CORDIC_Div_Result(void)
|
||||
{
|
||||
return CORDIC->ARCTAN & (CORDIC_ARCTAN_F_Msk | CORDIC_ARCTAN_I_Msk);
|
||||
}
|
||||
|
||||
#endif //__SWM341_CORDIC_H__
|
||||
@@ -0,0 +1,67 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_crc.c
|
||||
* 功能说明: SWM341单片机的CRC模块驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.1.0 2017年10月25日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_crc.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CRC_Init()
|
||||
* 功能说明: CRC 初始化
|
||||
* 输 入: CRC_TypeDef * CRCx 指定要被设置的CRC接口,有效值包括CRC
|
||||
* CRC_InitStructure * initStruct 包含CRC相关设定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CRC_Init(CRC_TypeDef * CRCx, CRC_InitStructure * initStruct)
|
||||
{
|
||||
switch((uint32_t)CRCx)
|
||||
{
|
||||
case ((uint32_t)CRC):
|
||||
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CRC_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
CRCx->INIVAL = initStruct->init_crc;
|
||||
|
||||
CRCx->CR = (1 << CRC_CR_EN_Pos) |
|
||||
(initStruct->Poly << CRC_CR_POLY_Pos) |
|
||||
(initStruct->in_width << CRC_CR_IBIT_Pos) |
|
||||
(initStruct->in_rev << CRC_CR_IREV_Pos) |
|
||||
(initStruct->in_not << CRC_CR_INOT_Pos) |
|
||||
(initStruct->out_rev << CRC_CR_OREV_Pos) |
|
||||
(initStruct->out_not << CRC_CR_ONOT_Pos);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CRC_SetInitVal()
|
||||
* 功能说明: 设置CRC计算初始值
|
||||
* 输 入: CRC_TypeDef * CRCx 指定要被设置的CRC接口,有效值包括CRC
|
||||
* uint32_t init_crc CRC计算初始值
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void CRC_SetInitVal(CRC_TypeDef * CRCx, uint32_t init_crc)
|
||||
{
|
||||
CRCx->INIVAL = init_crc;
|
||||
|
||||
CRCx->CR |= (1 << CRC_CR_EN_Pos);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef __SWM341_CRC_H__
|
||||
#define __SWM341_CRC_H__
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t init_crc; // 初始值
|
||||
uint8_t Poly; // CRC多项式,可取值CRC_POLY_11021、CRC_POLY_107、CRC_POLY_18005、CRC_POLY_104C11DB7
|
||||
uint8_t in_width; // 输入数据宽度,可取值CRC_WIDTH_32、CRC_WIDTH_16、CRC_WIDTH_8
|
||||
uint8_t in_rev; // 输入数据翻转,可取值CRC_REV_NOT、CRC_REV_ALL、CRC_REV_IN_BYTE、CRC_REV_BYTE
|
||||
bool in_not; // 输入数据取反
|
||||
uint8_t out_rev; // 输出结果翻转,可取值CRC_REV_NOT、CRC_REV_ALL、CRC_REV_IN_BYTE、CRC_REV_BYTE
|
||||
bool out_not; // 输出结果取反
|
||||
} CRC_InitStructure;
|
||||
|
||||
|
||||
#define CRC_POLY_11021 0 // x^16+x^12+x^5+1
|
||||
#define CRC_POLY_107 1 // x^8+x^2+x+1
|
||||
#define CRC_POLY_18005 2 // x^16+x^15+x^2+1
|
||||
#define CRC_POLY_104C11DB7 3 // x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
|
||||
|
||||
#define CRC_WIDTH_32 0
|
||||
#define CRC_WIDTH_16 1
|
||||
#define CRC_WIDTH_8 2
|
||||
|
||||
#define CRC_REV_NOT 0 // bit顺序不变
|
||||
#define CRC_REV_ALL 1 // bit顺序完全翻转
|
||||
#define CRC_REV_IN_BYTE 2 // bit顺序字节内翻转
|
||||
#define CRC_REV_BYTE 3 // 仅字节顺序翻转
|
||||
|
||||
|
||||
void CRC_Init(CRC_TypeDef * CRCx, CRC_InitStructure * initStruct);
|
||||
void CRC_SetInitVal(CRC_TypeDef * CRCx, uint32_t init_crc);
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CRC_Write()
|
||||
* 功能说明: CRC写入数据
|
||||
* 输 入: uint32_t data 要写入的数据
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void CRC_Write(uint32_t data)
|
||||
{
|
||||
CRC->DATAIN = data;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: CRC_Result()
|
||||
* 功能说明: 获取CRC计算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t CRC 计算结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t CRC_Result(void)
|
||||
{
|
||||
return CRC->RESULT;
|
||||
}
|
||||
|
||||
#endif //__SWM341_CRC_H__
|
||||
@@ -0,0 +1,70 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_dac.c
|
||||
* 功能说明: SWM341单片机的DAC模块驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.1.0 2017年10月25日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_dac.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DAC_Init()
|
||||
* 功能说明: DAC 初始化
|
||||
* 输 入: DAC_TypeDef * DACx 指定要被设置的DAC接口,有效值包括DAC
|
||||
* uint32_t format 数据格式,可取值DAC_FORMAT_LSB12B、DAC_FORMAT_MSB12B、DAC_FORMAT_8B
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DAC_Init(DAC_TypeDef * DACx, uint32_t format)
|
||||
{
|
||||
switch((uint32_t)DACx)
|
||||
{
|
||||
case ((uint32_t)DAC):
|
||||
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_DAC_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
SYS->DACCR &= ~SYS_DACCR_VRADJ_Msk;
|
||||
SYS->DACCR |= ((SYS->BACKUP[2] & 0x1F) << SYS_DACCR_VRADJ_Pos);
|
||||
|
||||
DACx->CR = (format << DAC_CR_DHRFMT_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DAC_Open()
|
||||
* 功能说明: DAC 开启
|
||||
* 输 入: DAC_TypeDef * DACx 指定要被设置的DAC接口,有效值包括DAC
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DAC_Open(DAC_TypeDef * DACx)
|
||||
{
|
||||
DACx->CR |= (1 << DAC_CR_EN_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DAC_Close()
|
||||
* 功能说明: DAC 关闭
|
||||
* 输 入: DAC_TypeDef * DACx 指定要被设置的DAC接口,有效值包括DAC
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DAC_Close(DAC_TypeDef * DACx)
|
||||
{
|
||||
DACx->CR &= ~DAC_CR_EN_Msk;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __SWM341_DAC_H__
|
||||
#define __SWM341_DAC_H__
|
||||
|
||||
|
||||
#define DAC_FORMAT_LSB12B 0 //12位数据,DHR[11:0] => DOR[11:0]
|
||||
#define DAC_FORMAT_MSB12B 1 //12位数据,DHR[15:4] => DOR[11:0]
|
||||
#define DAC_FORMAT_8B 3 // 8位数据,DHR[7 :0] => DOR[11:4]
|
||||
|
||||
|
||||
void DAC_Init(DAC_TypeDef * DACx, uint32_t format);
|
||||
void DAC_Open(DAC_TypeDef * DACx);
|
||||
void DAC_Close(DAC_TypeDef * DACx);
|
||||
|
||||
|
||||
#endif //__SWM341_DAC_H__
|
||||
@@ -0,0 +1,40 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_div.c
|
||||
* 功能说明: SWM341单片机的DIV硬件除法功能驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.0.0 2016年1月30日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_div.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_Init()
|
||||
* 功能说明: 硬件除法器初始化
|
||||
* 输 入: DIV_TypeDef * DIVx 指定要被设置的硬件除法器,有效值包括DIV
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DIV_Init(DIV_TypeDef * DIVx)
|
||||
{
|
||||
switch((uint32_t)DIVx)
|
||||
{
|
||||
case ((uint32_t)DIV):
|
||||
SYS->CLKEN0 |= (0x01u<< SYS_CLKEN0_DIV_Pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
#ifndef __SWM341_DIV_H__
|
||||
#define __SWM341_DIV_H__
|
||||
|
||||
|
||||
void DIV_Init(DIV_TypeDef * DIVx);
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_UDiv()
|
||||
* 功能说明: 使用硬件除法器执行无符号数除法运算
|
||||
* 输 入: uint32_t dividend 被除数
|
||||
* uint32_t divisor 除数
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void DIV_UDiv(uint32_t dividend, uint32_t divisor)
|
||||
{
|
||||
DIV->DIVIDEND = dividend;
|
||||
DIV->DIVISOR = divisor;
|
||||
|
||||
DIV->CR = (1 << DIV_CR_DIVSIGN_Pos) | (1 << DIV_CR_DIVGO_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_SDiv()
|
||||
* 功能说明: 使用硬件除法器执行有符号数除法运算
|
||||
* 输 入: int32_t dividend 被除数
|
||||
* int32_t divisor 除数
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void DIV_SDiv(int32_t dividend, int32_t divisor)
|
||||
{
|
||||
DIV->DIVIDEND = dividend;
|
||||
DIV->DIVISOR = divisor;
|
||||
|
||||
DIV->CR = (0 << DIV_CR_DIVSIGN_Pos) | (1 << DIV_CR_DIVGO_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_Div_IsBusy()
|
||||
* 功能说明: 硬件除法器是否正在执行除法运算
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 1 硬件除法器正在执行除法运算 0 硬件除法器已完成除法运算,可取出运算结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t DIV_Div_IsBusy(void)
|
||||
{
|
||||
return (DIV->SR & DIV_SR_DIVBUSY_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_UDiv_Result()
|
||||
* 功能说明: 取出硬件除法器的运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t *quotient 商
|
||||
* uint32_t *remainder 余数
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void DIV_UDiv_Result(uint32_t *quotient, uint32_t *remainder)
|
||||
{
|
||||
*quotient = DIV->QUO;
|
||||
*remainder = DIV->REMAIN;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_SDiv_Result()
|
||||
* 功能说明: 取出硬件除法器的运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: int32_t *quotient 商
|
||||
* int32_t *remainder 余数
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void DIV_SDiv_Result(int32_t *quotient, int32_t *remainder)
|
||||
{
|
||||
*quotient = DIV->QUO & 0x7FFFFFFF;
|
||||
if(DIV->QUO & (1u << 31)) *quotient = 0 - *quotient;
|
||||
|
||||
*remainder = DIV->REMAIN & 0x7FFFFFFF;
|
||||
if(DIV->REMAIN & (1u << 31)) *remainder = 0 - *remainder;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_Root()
|
||||
* 功能说明: 使用硬件开方模块执行开方运算
|
||||
* 输 入: uint32_t radicand 被开方数
|
||||
* uint32_t calcu_frac 0 开方结果为16位整数 1 开方结果为16位整数+16位小数
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE void DIV_Root(uint32_t radicand, uint32_t calcu_fractional)
|
||||
{
|
||||
DIV->RADICAND = radicand;
|
||||
|
||||
DIV->CR = (1 << DIV_CR_ROOTGO_Pos) | (calcu_fractional << DIV_CR_ROOTMOD_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_Root_IsBusy()
|
||||
* 功能说明: 硬件开方模块是否正在执行开方运算
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 1 硬件开方模块正在执行开方运算 0 硬件开方模块已完成开方运算,可取出运算结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t DIV_Root_IsBusy(void)
|
||||
{
|
||||
return (DIV->SR & DIV_SR_ROOTBUSY_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DIV_Root_Result()
|
||||
* 功能说明: 取出硬件开方模块的运算结果
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 开方结果
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
static __INLINE uint32_t DIV_Root_Result(void)
|
||||
{
|
||||
if(DIV->CR & DIV_CR_ROOTMOD_Msk)
|
||||
{
|
||||
return DIV->ROOT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DIV->ROOT >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //__SWM341_DIV_H__
|
||||
@@ -0,0 +1,242 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_dma.c
|
||||
* 功能说明: SWM341单片机的DMA功能驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.0.0 2016年1月30日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_dma.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_Init()
|
||||
* 功能说明: DMA通道初始化
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* DMA_InitStructure * initStruct 包含DMA通道相关设定值的结构体
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_Init(uint32_t chn, DMA_InitStructure * initStruct)
|
||||
{
|
||||
DMA->EN = 1; //每个通道都有自己独立的开关控制,所以总开关可以是一直开启的
|
||||
|
||||
DMA_CH_Close(chn); //关闭后配置
|
||||
|
||||
DMA->CH[chn].CR = (initStruct->Mode << DMA_CR_AUTORE_Pos) |
|
||||
((initStruct->Count ? initStruct->Count - 1 : 0) << DMA_CR_LEN_Pos);
|
||||
|
||||
DMA->CH[chn].SRC = initStruct->SrcAddr;
|
||||
DMA->CH[chn].DST = initStruct->DstAddr;
|
||||
|
||||
DMA->CH[chn].AM = (initStruct->SrcAddrInc << DMA_AM_SRCAM_Pos) |
|
||||
(initStruct->DstAddrInc << DMA_AM_DSTAM_Pos) |
|
||||
(initStruct->Unit << DMA_AM_SRCBIT_Pos) |
|
||||
(initStruct->Unit << DMA_AM_DSTBIT_Pos);
|
||||
|
||||
switch(initStruct->Handshake & DMA_HS_MSK)
|
||||
{
|
||||
case DMA_HS_NO:
|
||||
DMA->CH[chn].MUX = 0;
|
||||
break;
|
||||
|
||||
case DMA_HS_SRC:
|
||||
DMA->CH[chn].MUX = ((initStruct->Handshake & 0xF) << DMA_MUX_SRCHSSIG_Pos) | (1 << DMA_MUX_SRCHSEN_Pos);
|
||||
break;
|
||||
|
||||
case DMA_HS_DST:
|
||||
DMA->CH[chn].MUX = ((initStruct->Handshake & 0xF) << DMA_MUX_DSTHSSIG_Pos) | (1 << DMA_MUX_DSTHSEN_Pos);
|
||||
break;
|
||||
|
||||
case DMA_HS_EXT:
|
||||
DMA->CH[chn].MUX = ((initStruct->Handshake & 0xF) << DMA_MUX_EXTHSSIG_Pos) | (1 << DMA_MUX_EXTHSEN_Pos);
|
||||
DMA->CH[chn].CR |= (1 << DMA_CR_STEPOP_Pos);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int totalBytes = initStruct->Count * (1 << initStruct->Unit);
|
||||
|
||||
if(initStruct->DstAddrInc == 2) // Destination Scatter-Gather Transfer
|
||||
{
|
||||
DMA->CH[chn].DSTSGADDR1 = initStruct->DstAddr + totalBytes / 4 * 1;
|
||||
DMA->CH[chn].DSTSGADDR2 = initStruct->DstAddr + totalBytes / 4 * 2;
|
||||
DMA->CH[chn].DSTSGADDR3 = initStruct->DstAddr + totalBytes / 4 * 3;
|
||||
}
|
||||
if(initStruct->SrcAddrInc == 2) // Source Scatter-Gather Transfer
|
||||
{
|
||||
DMA->CH[chn].SRCSGADDR1 = initStruct->SrcAddr + totalBytes / 4 * 1;
|
||||
DMA->CH[chn].SRCSGADDR2 = initStruct->SrcAddr + totalBytes / 4 * 2;
|
||||
DMA->CH[chn].SRCSGADDR3 = initStruct->SrcAddr + totalBytes / 4 * 3;
|
||||
}
|
||||
|
||||
DMA->PRI &= ~(1 << chn);
|
||||
DMA->PRI |= (initStruct->Priority << chn);
|
||||
|
||||
DMA->IM |= (1 << chn); // 默认全部关闭
|
||||
DMA->DSTSGIM |= (3 << (chn * 2));
|
||||
DMA->SRCSGIM |= (3 << (chn * 2));
|
||||
DMA->IE |= (1 << chn); // 标志总是可查
|
||||
DMA->DSTSGIE |= (3 << (chn * 2));
|
||||
DMA->SRCSGIE |= (3 << (chn * 2));
|
||||
|
||||
DMA_CH_INTClr(chn, initStruct->INTEn);
|
||||
DMA_CH_INTEn(chn, initStruct->INTEn);
|
||||
|
||||
if(initStruct->INTEn) NVIC_EnableIRQ(DMA_IRQn);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_Open()
|
||||
* 功能说明: DMA通道开启,对于软件启动通道,开启后立即传输;对于硬件触发通道,开启后还需等出现触发信号后才开始搬运
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_Open(uint32_t chn)
|
||||
{
|
||||
DMA->CH[chn].CR |= (1 << DMA_CR_RXEN_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_Close()
|
||||
* 功能说明: DMA通道关闭
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_Close(uint32_t chn)
|
||||
{
|
||||
DMA->CH[chn].CR &= ~(DMA_CR_TXEN_Msk | DMA_CR_RXEN_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_SetCount()
|
||||
* 功能说明: 设置传输 Unit 个数
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t count 传输 Unit 个数,最大取值0x100000
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_SetCount(uint32_t chn, uint32_t count)
|
||||
{
|
||||
DMA->CH[chn].CR &= ~DMA_CR_LEN_Msk;
|
||||
DMA->CH[chn].CR |= ((count - 1) << DMA_CR_LEN_Pos);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_GetRemaining()
|
||||
* 功能说明: 查询剩余的传输 Unit 个数
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* 输 出: uint32_t 剩余的传输 Unit 个数
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t DMA_CH_GetRemaining(uint32_t chn)
|
||||
{
|
||||
return (DMA->CH[chn].DSTSR & DMA_DSTSR_LEN_Msk);
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_SetSrcAddress()
|
||||
* 功能说明: 设置传输源地址
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t address 源地址
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_SetSrcAddress(uint32_t chn, uint32_t address)
|
||||
{
|
||||
DMA->CH[chn].SRC = address;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_SetDstAddress()
|
||||
* 功能说明: 设置传输目的地址
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t address 目的地址
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_SetDstAddress(uint32_t chn, uint32_t address)
|
||||
{
|
||||
DMA->CH[chn].DST = address;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_INTEn()
|
||||
* 功能说明: DMA中断使能
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t it interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
|
||||
* DMA_IT_SRCSG_DONE 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_INTEn(uint32_t chn, uint32_t it)
|
||||
{
|
||||
DMA->IM &= ~(it << chn);
|
||||
DMA->DSTSGIM &= ~((it >> 8) << (chn * 2));
|
||||
DMA->SRCSGIM &= ~((it >> 16) << (chn * 2));
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_INTDis()
|
||||
* 功能说明: DMA中断禁止
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t it interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
|
||||
* DMA_IT_SRCSG_DONE 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_INTDis(uint32_t chn, uint32_t it)
|
||||
{
|
||||
DMA->IM |= (it << chn);
|
||||
DMA->DSTSGIM |= ((it >> 8) << (chn * 2));
|
||||
DMA->SRCSGIM |= ((it >> 16) << (chn * 2));
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_INTClr()
|
||||
* 功能说明: DMA中断标志清除
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t it interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
|
||||
* DMA_IT_SRCSG_DONE 及其“或”
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA_CH_INTClr(uint32_t chn, uint32_t it)
|
||||
{
|
||||
DMA->IF = (it << chn);
|
||||
DMA->DSTSGIF = ((it >> 8) << (chn * 2));
|
||||
DMA->SRCSGIF = ((it >> 16) << (chn * 2));
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA_CH_INTStat()
|
||||
* 功能说明: DMA中断状态查询
|
||||
* 输 入: uint32_t chn 指定要配置的通道,有效值有DMA_CH0、DMA_CH1、DMA_CH2、DMA_CH3
|
||||
* uint32_t it interrupt type,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、
|
||||
* DMA_IT_SRCSG_DONE 及其“或”
|
||||
* 输 出: uint32_t 1 指定中断已发生 0 指定中断未发生
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t DMA_CH_INTStat(uint32_t chn, uint32_t it)
|
||||
{
|
||||
return ((DMA->IF & (it << chn)) ||
|
||||
(DMA->DSTSGIF & ((it >> 8) << (chn * 2))) ||
|
||||
(DMA->SRCSGIF & ((it >> 16) << (chn * 2))));
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef __SWM341_DMA_H__
|
||||
#define __SWM341_DMA_H__
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t Mode; //DMA_MODE_SINGLE、DMA_MODE_CIRCLE
|
||||
|
||||
uint8_t Unit; //DMA_UNIT_BYTE、DMA_UNIT_HALFWORD、DMA_UNIT_WORD
|
||||
|
||||
uint32_t Count; //传输 Unit 个数,最大取值0x100000
|
||||
|
||||
uint32_t SrcAddr;
|
||||
|
||||
uint32_t DstAddr;
|
||||
|
||||
uint8_t SrcAddrInc; //0 地址固定 1 地址递增
|
||||
|
||||
uint8_t DstAddrInc;
|
||||
|
||||
uint8_t Handshake; //传输握手信号:DMA_HS_NO、DMA_CH0_UART0TX、DMA_CH0_SPI0TX、... ...
|
||||
|
||||
uint8_t Priority; //DMA_PRI_LOW、DMA_PRI_HIGH
|
||||
|
||||
uint32_t INTEn; //中断使能,有效值有 DMA_IT_DONE、DMA_IT_DSTSG_HALF、DMA_IT_DSTSG_DONE、DMA_IT_SRCSG_HALF、DMA_IT_SRCSG_DONE 及其“或”
|
||||
} DMA_InitStructure;
|
||||
|
||||
|
||||
#define DMA_CH0 0
|
||||
#define DMA_CH1 1
|
||||
#define DMA_CH2 2
|
||||
#define DMA_CH3 3
|
||||
|
||||
#define DMA_MODE_SINGLE 0 // 单次模式,传输完成后停止
|
||||
#define DMA_MODE_CIRCLE 1 // 环形模式,传输完成后从头执行下一轮传输
|
||||
|
||||
#define DMA_UNIT_BYTE 0
|
||||
#define DMA_UNIT_HALFWORD 1
|
||||
#define DMA_UNIT_WORD 2
|
||||
|
||||
#define DMA_PRI_LOW 0
|
||||
#define DMA_PRI_HIGH 1
|
||||
|
||||
|
||||
#define DMA_HS_NO (0 << 4) // 无握手(Handshake)信号,启动传输后全部传完
|
||||
#define DMA_HS_SRC (1 << 4) // 源 侧握手信号,启动传输后源 侧生成一个数据,DMA搬运一个Unit
|
||||
#define DMA_HS_DST (2 << 4) // 目标侧握手信号,启动传输后目标侧索取一个数据,DMA搬运一个Unit
|
||||
#define DMA_HS_EXT (4 << 4) // 外部 握手信号,启动传输后外部握手来一个脉冲,DMA搬运一个Unit
|
||||
#define DMA_HS_MSK (7 << 4)
|
||||
|
||||
#define DMA_DIR_RX (0 << 7) // SRC --> DST
|
||||
#define DMA_DIR_TX (1 << 7) // DST --> SRC
|
||||
#define DMA_DIR_MSK (1 << 7)
|
||||
|
||||
// 源侧外设
|
||||
#define DMA_CH0_UART1RX (0 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH0_SPI1RX (1 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH0_UART2RX (2 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH0_ADC0 (3 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH1_UART0RX (0 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH1_SPI0RX (1 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH1_UART3RX (2 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH2_UART3RX (0 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH2_SPI0RX (1 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH2_UART0RX (2 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH3_UART2RX (0 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH3_SPI1RX (1 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH3_UART1RX (2 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
#define DMA_CH3_ADC1 (3 | DMA_HS_SRC | DMA_DIR_RX)
|
||||
|
||||
// 目标侧外设
|
||||
#define DMA_CH0_UART0TX (0 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH0_SPI0TX (1 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH0_UART3TX (2 | DMA_HS_DST | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH1_UART1TX (0 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH1_SPI1TX (1 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH1_UART2TX (2 | DMA_HS_DST | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH2_UART2TX (0 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH2_SPI1TX (1 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH2_UART1TX (2 | DMA_HS_DST | DMA_DIR_RX)
|
||||
|
||||
#define DMA_CH3_UART3TX (0 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH3_SPI0TX (1 | DMA_HS_DST | DMA_DIR_RX)
|
||||
#define DMA_CH3_UART0TX (2 | DMA_HS_DST | DMA_DIR_RX)
|
||||
|
||||
// 外部握手信号
|
||||
#define DMA_EXHS_TIMR0 (0 | DMA_HS_EXT | DMA_DIR_RX)
|
||||
#define DMA_EXHS_TIMR1 (1 | DMA_HS_EXT | DMA_DIR_RX)
|
||||
#define DMA_EXHS_TIMR2 (2 | DMA_HS_EXT | DMA_DIR_RX)
|
||||
#define DMA_EXHS_TIMR3 (3 | DMA_HS_EXT | DMA_DIR_RX)
|
||||
#define DMA_EXHS_TIMR4 (4 | DMA_HS_EXT | DMA_DIR_RX)
|
||||
#define DMA_EXHS_TRIG0 (5 | DMA_HS_EXT | DMA_DIR_RX) // DMA_TRIG0引脚
|
||||
#define DMA_EXHS_TRIG1 (6 | DMA_HS_EXT | DMA_DIR_RX) // DMA_TRIG1引脚
|
||||
|
||||
|
||||
/* Interrupt Type */
|
||||
#define DMA_IT_DONE (1 << 0) //Transfer Done
|
||||
#define DMA_IT_DSTSG_HALF (1 << 8) //Destination Scatter-Gather Transfer Half
|
||||
#define DMA_IT_DSTSG_DONE (1 << 9) //Destination Scatter-Gather Transfer Done
|
||||
#define DMA_IT_SRCSG_HALF (1 << 16) //Source Scatter-Gather Transfer Half
|
||||
#define DMA_IT_SRCSG_DONE (1 << 17) //Source Scatter-Gather Transfer Done
|
||||
|
||||
|
||||
|
||||
void DMA_CH_Init(uint32_t chn, DMA_InitStructure * initStruct); //DMA通道配置
|
||||
void DMA_CH_Open(uint32_t chn);
|
||||
void DMA_CH_Close(uint32_t chn);
|
||||
|
||||
void DMA_CH_SetCount(uint32_t chn, uint32_t count);
|
||||
void DMA_CH_SetSrcAddress(uint32_t chn, uint32_t address);
|
||||
void DMA_CH_SetDstAddress(uint32_t chn, uint32_t address);
|
||||
uint32_t DMA_CH_GetRemaining(uint32_t chn);
|
||||
|
||||
void DMA_CH_INTEn(uint32_t chn, uint32_t it); //DMA中断使能
|
||||
void DMA_CH_INTDis(uint32_t chn, uint32_t it); //DMA中断禁止
|
||||
void DMA_CH_INTClr(uint32_t chn, uint32_t it); //DMA中断标志清除
|
||||
uint32_t DMA_CH_INTStat(uint32_t chn, uint32_t it); //DMA中断状态查询
|
||||
|
||||
|
||||
#endif //__SWM341_DMA_H__
|
||||
@@ -0,0 +1,220 @@
|
||||
/******************************************************************************************************************************************
|
||||
* 文件名称: SWM341_dma2d.c
|
||||
* 功能说明: SWM341单片机的DMA2D功能驱动库
|
||||
* 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
|
||||
* 注意事项:
|
||||
* 版本日期: V1.0.0 2016年1月30日
|
||||
* 升级记录:
|
||||
*
|
||||
*
|
||||
*******************************************************************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
|
||||
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
|
||||
* -ECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2012 Synwit Technology
|
||||
*******************************************************************************************************************************************/
|
||||
#include "SWM341.h"
|
||||
#include "SWM341_dma2d.h"
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_Init()
|
||||
* 功能说明: DMA2D初始化
|
||||
* 输 入: DMA2D_InitStructure * initStruct
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_Init(DMA2D_InitStructure * initStruct)
|
||||
{
|
||||
SYS->CLKEN0 |= (1 << SYS_CLKEN0_DMA2D_Pos);
|
||||
|
||||
DMA2D->CR &= ~DMA2D_CR_WAIT_Msk;
|
||||
DMA2D->CR |= (initStruct->Interval << DMA2D_CR_WAIT_Pos);
|
||||
|
||||
DMA2D->IF = 0xFF;
|
||||
DMA2D->IE = (initStruct->IntEOTEn << DMA2D_IE_DONE_Pos);
|
||||
|
||||
if(initStruct->IntEOTEn)
|
||||
NVIC_EnableIRQ(DMA2D_IRQn);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_PixelFill()
|
||||
* 功能说明: DMA2D向指定存储器区域填充指定颜色
|
||||
* 输 入: DMA2D_LayerSetting * outLayer 要填充的位置、大小、颜色格式等
|
||||
* uint32_t color 要填充的颜色
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_PixelFill(DMA2D_LayerSetting * outLayer, uint32_t color)
|
||||
{
|
||||
DMA2D->L[DMA2D_LAYER_OUT].COLOR = color;
|
||||
|
||||
DMA2D->L[DMA2D_LAYER_OUT].MAR = outLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].OR = outLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].PFCCR = (outLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos);
|
||||
|
||||
DMA2D->NLR = ((outLayer->LineCount - 1) << DMA2D_NLR_NLINE_Pos) |
|
||||
((outLayer->LinePixel - 1) << DMA2D_NLR_NPIXEL_Pos);
|
||||
|
||||
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
|
||||
DMA2D->CR |= (3 << DMA2D_CR_MODE_Pos) |
|
||||
(1 << DMA2D_CR_START_Pos);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_PixelMove()
|
||||
* 功能说明: DMA2D像素数据搬运
|
||||
* 输 入: DMA2D_LayerSetting * fgLayer
|
||||
* DMA2D_LayerSetting * outLayer
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_PixelMove(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * outLayer)
|
||||
{
|
||||
DMA2D->L[DMA2D_LAYER_FG].MAR = fgLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_FG].OR = fgLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_FG].PFCCR = (fgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos);
|
||||
|
||||
DMA2D->L[DMA2D_LAYER_OUT].MAR = outLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].OR = outLayer->LineOffset;
|
||||
|
||||
DMA2D->NLR = ((outLayer->LineCount - 1) << DMA2D_NLR_NLINE_Pos) |
|
||||
((outLayer->LinePixel - 1) << DMA2D_NLR_NPIXEL_Pos);
|
||||
|
||||
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
|
||||
DMA2D->CR |= (0 << DMA2D_CR_MODE_Pos) |
|
||||
(1 << DMA2D_CR_START_Pos);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_PixelConvert()
|
||||
* 功能说明: DMA2D像素转换
|
||||
* 输 入: DMA2D_LayerSetting * fgLayer
|
||||
* DMA2D_LayerSetting * outLayer
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_PixelConvert(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * outLayer)
|
||||
{
|
||||
DMA2D->L[DMA2D_LAYER_FG].MAR = fgLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_FG].OR = fgLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_FG].PFCCR = (fgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos);
|
||||
|
||||
DMA2D->L[DMA2D_LAYER_OUT].MAR = outLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].OR = outLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].PFCCR = (outLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos);
|
||||
|
||||
DMA2D->NLR = ((outLayer->LineCount - 1) << DMA2D_NLR_NLINE_Pos) |
|
||||
((outLayer->LinePixel - 1) << DMA2D_NLR_NPIXEL_Pos);
|
||||
|
||||
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
|
||||
DMA2D->CR |= (1 << DMA2D_CR_MODE_Pos) |
|
||||
(1 << DMA2D_CR_START_Pos);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_PixelBlend()
|
||||
* 功能说明: DMA2D像素混合
|
||||
* 输 入: DMA2D_LayerSetting * fgLayer
|
||||
* DMA2D_LayerSetting * bgLayer
|
||||
* DMA2D_LayerSetting * outLayer
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_PixelBlend(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * bgLayer, DMA2D_LayerSetting * outLayer)
|
||||
{
|
||||
DMA2D->L[DMA2D_LAYER_FG].MAR = fgLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_FG].OR = fgLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_FG].PFCCR = (fgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos) |
|
||||
(fgLayer->AlphaMode << DMA2D_PFCCR_AINV_Pos) |
|
||||
(fgLayer->Alpha << DMA2D_PFCCR_ALPHA_Pos);
|
||||
|
||||
DMA2D->L[DMA2D_LAYER_BG].MAR = bgLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_BG].OR = bgLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_BG].PFCCR = (bgLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos) |
|
||||
(bgLayer->AlphaMode << DMA2D_PFCCR_AINV_Pos) |
|
||||
(bgLayer->Alpha << DMA2D_PFCCR_ALPHA_Pos);
|
||||
|
||||
DMA2D->L[DMA2D_LAYER_OUT].MAR = outLayer->Address;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].OR = outLayer->LineOffset;
|
||||
DMA2D->L[DMA2D_LAYER_OUT].PFCCR = (outLayer->ColorMode << DMA2D_PFCCR_CFMT_Pos);
|
||||
|
||||
DMA2D->NLR = ((outLayer->LineCount - 1) << DMA2D_NLR_NLINE_Pos) |
|
||||
((outLayer->LinePixel - 1) << DMA2D_NLR_NPIXEL_Pos);
|
||||
|
||||
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
|
||||
DMA2D->CR |= (2 << DMA2D_CR_MODE_Pos) |
|
||||
(1 << DMA2D_CR_START_Pos);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_IsBusy()
|
||||
* 功能说明: DMA2D忙查询
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 1 正在传输 0 传输完成
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t DMA2D_IsBusy(void)
|
||||
{
|
||||
return (DMA2D->CR & DMA2D_CR_START_Msk) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_INTEn()
|
||||
* 功能说明: DMA2D中断使能,完成指定长度的数据传输时触发中断
|
||||
* 输 入: 无
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_INTEn(void)
|
||||
{
|
||||
DMA2D->IE = DMA2D_IE_DONE_Msk;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_INTDis()
|
||||
* 功能说明: DMA2D中断禁止,完成指定长度的数据传输时不触发中断
|
||||
* 输 入: 无
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_INTDis(void)
|
||||
{
|
||||
DMA2D->IE = 0;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_INTClr()
|
||||
* 功能说明: DMA2D中断标志清除
|
||||
* 输 入: 无
|
||||
* 输 出: 无
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
void DMA2D_INTClr(void)
|
||||
{
|
||||
DMA2D->IF = DMA2D_IF_DONE_Msk;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************************************
|
||||
* 函数名称: DMA2D_INTStat()
|
||||
* 功能说明: DMA2D中断状态查询
|
||||
* 输 入: 无
|
||||
* 输 出: uint32_t 0 未完成指定长度的数据传输 1 完成指定长度的数据传输
|
||||
* 注意事项: 无
|
||||
******************************************************************************************************************************************/
|
||||
uint32_t DMA2D_INTStat(void)
|
||||
{
|
||||
return (DMA2D->IF & DMA2D_IF_DONE_Msk) ? 1 : 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef __SWM341_DMA2D_H__
|
||||
#define __SWM341_DMA2D_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t Interval; // 每传输一块数据(64个字),等待指定个系统周期后再传输下一个块,防止DMA2D占用过多SDRAM带宽,影响LCD读取显示数据;取值1--1023
|
||||
uint8_t IntEOTEn; // End of Transter(传输完成)中断使能
|
||||
} DMA2D_InitStructure;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t Address;
|
||||
uint32_t LineOffset; // added at the end of each line to determine the starting address of the next line
|
||||
uint8_t ColorMode; // DMA2D_FMT_ARGB888、DMA2D_FMT_RGB888、DMA2D_FMT_RGB565、...
|
||||
uint8_t AlphaMode; // DMA2D_AMODE_PIXEL、DMA2D_AMODE_ALPHA、DMA2D_AMODE_PMULA、...
|
||||
uint8_t Alpha;
|
||||
|
||||
/* 只有输出层需要设置这两个域,前景层和背景层不需设置 */
|
||||
uint16_t LineCount; // 显示数据行数
|
||||
uint16_t LinePixel; // 每行像素个数
|
||||
} DMA2D_LayerSetting;
|
||||
|
||||
|
||||
#define DMA2D_LAYER_FG 0 // Foreground layer
|
||||
#define DMA2D_LAYER_BG 1 // Background layer
|
||||
#define DMA2D_LAYER_OUT 2 // Output layer
|
||||
|
||||
/* Color Format */
|
||||
#define DMA2D_FMT_ARGB888 (0 | (0 << 4))
|
||||
#define DMA2D_FMT_RGB888 (1 | (0 << 4))
|
||||
#define DMA2D_FMT_RGB565 (2 | (0 << 4))
|
||||
#define DMA2D_FMT_ABGR888 (0 | (1 << 4))
|
||||
#define DMA2D_FMT_BGR888 (1 | (1 << 4))
|
||||
#define DMA2D_FMT_BGR565 (2 | (1 << 4))
|
||||
|
||||
/* Alpha Mode */
|
||||
#define DMA2D_AMODE_PIXEL (0 | (0 << 5)) // 使用像素点自带Alpha值
|
||||
#define DMA2D_AMODE_ALPHA (0 | (1 << 5)) // 使用软件指定的Alpha值
|
||||
#define DMA2D_AMODE_PMULA (0 | (2 << 5)) // 使用像素点自带Alpha值与软件指定的Alpha值的乘积
|
||||
|
||||
|
||||
void DMA2D_Init(DMA2D_InitStructure * initStruct);
|
||||
void DMA2D_PixelFill(DMA2D_LayerSetting * outLayer, uint32_t color);
|
||||
void DMA2D_PixelMove(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * outLayer);
|
||||
void DMA2D_PixelConvert(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * outLayer);
|
||||
void DMA2D_PixelBlend(DMA2D_LayerSetting * fgLayer, DMA2D_LayerSetting * bgLayer, DMA2D_LayerSetting * outLayer);
|
||||
uint32_t DMA2D_IsBusy(void);
|
||||
|
||||
void DMA2D_INTEn(void);
|
||||
void DMA2D_INTDis(void);
|
||||
void DMA2D_INTClr(void);
|
||||
uint32_t DMA2D_INTStat(void);
|
||||
|
||||
|
||||
#endif // __SWM341_DMA2D_H__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user