diff --git a/dwt_delay.c b/dwt_delay.c new file mode 100644 index 0000000..4ca8ba5 --- /dev/null +++ b/dwt_delay.c @@ -0,0 +1,63 @@ +#include + +extern uint32_t SystemCoreClock; + + +//定义需使能位 +#define DEM_CR_TRCENA (1u<<24) +#define DWT_CR_CYCCNTENA (1u<<0) + + +//DWT init +void DWT_Init(void) +{ + DEM_CR |= (uint32_t)DEM_CR_TRCENA; + DWT_CYCCNT = (uint32_t)0u; + DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA; +} + +void DWT_DelayUs(uint32_t us) +{ + uint32_t start = DWT_CYCCNT; + uint32_t cycles = us * (SystemCoreClock / 1000000); + uint32_t elapsed; + + while (1) { + uint32_t current = DWT_CYCCNT; + if (current >= start) { + elapsed = current - start; + } else { + elapsed = (0xFFFFFFFFu - start) + current; // 处理溢出 + } + if (elapsed >= cycles) break; + } +} + +void DWT_DelayMs(uint32_t ms) +{ + for (uint32_t i = 0; i < ms; i++) { + DWT_DelayUs(1000); + } +} + +//使用DWT测量函数运行时间 +float DTW_Time_DiffMs(volatile uint32_t start, volatile uint32_t stop) +{ + uint32_t diff; + if(stop > start) + diff = stop - start; + else + diff = stop + 0XFFFFFFFFu - start; + return (diff / (SystemCoreClock/1000)); +} + +float DTW_Time_DiffUs(volatile uint32_t start, volatile uint32_t stop) +{ + uint32_t diff; + if(stop > start) + diff = stop - start; + else + diff = stop + 0XFFFFFFFFu - start; + return (diff / (SystemCoreClock/1000000)); +} + diff --git a/dwt_delay.h b/dwt_delay.h new file mode 100644 index 0000000..05ae880 --- /dev/null +++ b/dwt_delay.h @@ -0,0 +1,38 @@ +#ifndef INCLUDED_DWT_DELAY_H +#define INCLUDED_DWT_DELAY_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#endif /*INCLUDED_OS_COMPILER_H*/ + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +//寄存器基地址 +#define DWT_CR *(uint32_t*)0xE0001000 +#define DWT_CYCCNT *(uint32_t*)0xE0001004 +#define DEM_CR *(uint32_t*)0xE000EDFC + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +OS_STATIC_FORCE_INLINE +uint32_t DWT_Get(void){ + return ((uint32_t )DWT_CYCCNT); +} + +void DWT_Init(void); + +void DWT_DelayUs(uint32_t us); + +void DWT_DelayMs(uint32_t ms); + +float DTW_Time_DiffMs(volatile uint32_t start, volatile uint32_t stop); + +float DTW_Time_DiffUs(volatile uint32_t start, volatile uint32_t stop); + +#endif /*INCLUDED_DWT_DELAY_H*/ diff --git a/os_loopdelay.c b/os_loopdelay.c new file mode 100644 index 0000000..3938889 --- /dev/null +++ b/os_loopdelay.c @@ -0,0 +1,25 @@ +#include + +#if defined (__CC_ARM) /*!< ARM Compiler */ +__asm void os_loop_delay(unsigned long ulCount) +{ + subs r0, #1; + bne os_loop_delay; + bx lr; +} +#elif defined ( __ICCARM__ ) /*!< IAR Compiler */ +void os_loop_delay(unsigned long ulCount) +{ + __asm(" subs r0, #1 \n" + " bne.n os_loop_delay \n" + " bx lr"); +} + +#elif defined (__GNUC__) /*!< GNU Compiler */ +__attribute__((naked)) +void os_loop_delay(unsigned long ulCount){ + __asm(" subs r0, #1 \n" + " bne os_loop_delay \n" + " bx lr"); +} +#endif /* __CC_ARM */ \ No newline at end of file diff --git a/os_loopdelay.h b/os_loopdelay.h new file mode 100644 index 0000000..ba0bacd --- /dev/null +++ b/os_loopdelay.h @@ -0,0 +1,34 @@ +#ifndef INCLUDED_OS_LOOPDELAY_H +#define INCLUDED_OS_LOOPDELAY_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#define OS_LOOP_DELAY_US(n) (n * SystemCoreClock/3000000) +#define OS_LOOP_DELAY_MS(n) (n * SystemCoreClock/3000) +#define OS_LOOP_DELAY_S(n) (n * SystemCoreClock/3) + +/* + + 72Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/72us=1/24us + + SystemCoreClock=72000000 + + us级延时,延时n微秒 + LoopDelay(n*(SystemCoreClock/3000000)); + + ms级延时,延时n毫秒 + LoopDelay(n*(SystemCoreClock/3000)); + + m级延时,延时n秒 + LoopDelay(n*(SystemCoreClock/3)); +*/ + +void os_loop_delay(unsigned long ulCount); + +#define OS_LoopDelayUS(n) os_loop_delay(OS_LOOP_DELAY_US(n)) +#define OS_LoopDelayMS(n) os_loop_delay(OS_LOOP_DELAY_MS(n)) +#define OS_LoopDelayS(n) os_loop_delay(OS_LOOP_DELAY_S(n)) + +#endif /*INCLUDED_OS_LOOPDELAY_H*/ diff --git a/os_mpu.c b/os_mpu.c new file mode 100644 index 0000000..085db57 --- /dev/null +++ b/os_mpu.c @@ -0,0 +1 @@ +#include diff --git a/os_mpu.h b/os_mpu.h new file mode 100644 index 0000000..8e410c2 --- /dev/null +++ b/os_mpu.h @@ -0,0 +1,251 @@ +#ifndef INCLUDED_OS_MPU_H +#define INCLUDED_OS_MPU_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#endif /*INCLUDED_OS_COMPILER_H*/ + +#ifndef INCLUDED_CPU_H +#include +#endif /*INCLUDED_CPU_H*/ + + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +typedef struct { + os_uintptr_t TYPE; /* 提供 MPU 信息 */ + os_uintptr_t CTRL; /* MPU使能/禁止的背景区域控制 */ + os_uintptr_t RNR; /* 选择待配置的MPU区域 */ + os_uintptr_t RBAR; /* 定义MPU区域的基地址 */ + os_uintptr_t RASR; /* 定义MPU区域的属性和大小 */ + os_uintptr_t RBAR_A1; /* RBAR的别名 */ + os_uintptr_t RBSR_A1; /* RASR的别名 */ + os_uintptr_t RBAR_A2; /* RBAR的别名 */ + os_uintptr_t RBSR_A2; /* RASR的别名 */ + os_uintptr_t RBAR_A3; /* RBAR的别名 */ + os_uintptr_t RBSR_A3; /* RASR的别名 */ +}os_mpu_t; + +#define OS_MPU ((os_mpu_t*)(0xE000ED90u)) + +OS_PACKED_STRUCT(os_mpu_type_t){ + os_uint_t SEPARATE:1; + os_uint_t RESERVED_0:7; + os_uint_t DREGION:8; + os_uint_t IREGION:8; + os_uint_t RESERVED_1:8; +}os_mpu_type_t; + +OS_PACKED_STRUCT(os_mpu_ctrl_t){ + os_uint_t ENABLE:1; + os_uint_t HFNMIENA:1; + os_uint_t PRIVDEFENA:1; + os_uint_t RESERVED:29; +}os_mpu_ctrl_t; + +OS_PACKED_STRUCT(os_mpu_rnr_t){ + os_uint_t REGION:8; + os_uint_t RESERVED:24; +}os_mpu_rnr_t; + +OS_PACKED_STRUCT(os_mpu_rbar_t){ + os_uint_t REGION:4; + os_uint_t VALID:1; + os_uint_t ADDR:27; +}os_mpu_rbar_t; + +OS_PACKED_STRUCT(os_mpu_rasr_t){ + os_uint_t ENABLE:1; /* 区域使能 */ + os_uint_t SIZE:5; /* MPU保护区域大小 */ + os_uint_t RESERVED_0:2; + os_uint_t SRD:8; /* 子区域禁止 */ + os_uint_t B:1; /* 可缓冲 */ + os_uint_t C:1; /* 可缓存 */ + os_uint_t S:1; /* 可共用 */ + os_uint_t TEX:3; /* 类型展开域 */ + os_uint_t RESERVED_1:2; /* 保留 */ + os_uint_t AP:3; /* 数据访问允许域 */ + os_uint_t RESERVED_2:1; /* 保留 */ + os_uint_t XN:1; /* 指令访问禁止(1=禁止该区域的取值, 非要这么做会引发存储器管理错误) */ + os_uint_t RESERVED_3:3; /* 保留 */ +}os_mpu_rasr_t; + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ +#define OS_MPU_RASR_ENABLE_Pos 0 +#define OS_MPU_RASR_SIZE_Pos 1 +#define OS_MPU_RASR_SRD_Pos 8 +#define OS_MPU_RASR_B_Pos 16 +#define OS_MPU_RASR_C_Pos 17 +#define OS_MPU_RASR_S_Pos 18 +#define OS_MPU_RASR_TEX_Pos 19 +#define OS_MPU_RASR_AP_Pos 24 +#define OS_MPU_RASR_XN_Pos 28 + + +#define OS_MPU_DEFS_RASR_SIZE_32B (0x04<CTRL = OS_MPU_CTRL_ENABLE_Msk | options; + __DMB(); + __ISB(); +} + +OS_STATIC_FORCE_INLINE +void os_mpu_disable(void){ + __DMB(); + OS_MPU->CTRL = 0; +} + +OS_STATIC_FORCE_INLINE +void os_mpu_region_disable(os_uint_t region_num){ + OS_MPU->RNR = region_num; + OS_MPU->RBAR = 0; + OS_MPU->RASR = 0; +} + +OS_STATIC_FORCE_INLINE +void os_mpu_region_config(os_uint_t region_num, os_uintptr_t addr, os_size_t size, os_uint_t attribute){ + OS_MPU->RNR = region_num; + OS_MPU->RBAR = addr; + OS_MPU->RASR = ((size << OS_MPU_RASR_SIZE_Pos) & OS_MPU_RASR_SIZE_Msk) | attribute; +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* Example */ + +#if 0 + +/* 以下是 MPU 配置示例 */ + +int mpu_setup(void){ + if(OS_MPU->TYPE == 0){ return 1; /* 错误 */ } + os_mpu_disable(); + /* 0 - Flash */ + os_mpu_region_config(0 + , 0x08000000 + , OS_MPU_DEFS_RASR_SIZE_1MB + , OS_MPU_DEFS_NORMAL_MEMORY_WT | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); + /* 1 - SRAM */ + os_mpu_region_config(1 + , 0x20000000 + , OS_MPU_DEFS_RASR_SIZE_128KB + , OS_MPU_DEFS_NORMAL_MEMORY_WT | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); + + /* 2 - GPIOD */ + os_mpu_region_config(2 + , GPIOD_BASE + , OS_MPU_DEFS_RASR_SIZE_1KB + , OS_MPU_DEFS_SHARED_DEVICE | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); + + /* 3 - 复位时钟 */ + os_mpu_region_config(3 + , RCC_BASE + , OS_MPU_DEFS_RASR_SIZE_1KB + , OS_MPU_DEFS_SHARED_DEVICE | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); + + os_mpu_region_disable(4); + os_mpu_region_disable(5); + os_mpu_region_disable(6); + os_mpu_region_disable(7); + + os_mpu_enable(0); /* 使能MPU,无需其它设置 */ + return 0; /* 无错误 */ +} +#endif /* 0 */ + + +#endif /*INCLUDED_OS_MPU_H*/