Compare commits
No commits in common. "main" and "master" have entirely different histories.
|
@ -0,0 +1,69 @@
|
|||
# 异常报告
|
||||
|
||||
已知可能出现的bug将会列在此处,并指明修复期限和任务执行者。
|
||||
|
||||
使用中遇到的bug和错误放在此处。参照下列格式:
|
||||
|
||||
## 标题用简短的一句话描述
|
||||
|
||||
### 出现问题的application/module/bsp
|
||||
|
||||
描述你的使用方法,应该贴上图片或代码块,以及硬件连线等
|
||||
|
||||
### 尝试解决的方案
|
||||
|
||||
你的尝试,以及猜测可能的错误
|
||||
|
||||
### 如何复现问题
|
||||
|
||||
问题能否稳定复现?描述复现方法等
|
||||
|
||||
### 紧急程度
|
||||
|
||||
这里用⭐表示。最大5颗⭐。
|
||||
|
||||
如果不修复,会有何种其他牵连情况发生?
|
||||
|
||||
---
|
||||
|
||||
不同的问题用 --- 分隔开
|
||||
|
||||
你还可以使用Stepsize插件在代码出现问题(可能出现问题)的地方添加issues并详尽描述。或在gitee上增加issues。
|
||||
|
||||
当然,最快的方法是在群里提问。
|
||||
|
||||
## 使用LK电机并挂载在hcan2上时会出现HardFault
|
||||
|
||||
> 已修复此问题。修复日志请查看当前目录下的“如何定位bug.md”。
|
||||
|
||||
使用MF9025v2电机,并将其配置在CAN2上。经过一次LKMotorControl,第二次进入时hcan->instance会在HAL_CAN_Add_Tx_Message()结束时被未知的语句修改成奇怪的值,造成HardFault
|
||||
|
||||
### 尝试解决的方案
|
||||
|
||||
单步调试无果,在HAL_CAN_Add_Tx_Message()返回的那一步hcan->instance会莫名其妙变成0,hcan2也会被修改到一个0x8000xxx的地址上(hcan是HAL库自定的全局变量)
|
||||
|
||||
### 如何复现问题
|
||||
|
||||
使用LK电机并将其挂载在CAN2上,连接电机后直接运行。在第二次进入MotorTAsk中的LKMotorControl时,于检查空闲CAN邮箱时,由于hcan2被修改,访问CAN2外设状态时会访问野指针导致HardFault。
|
||||
|
||||
### 紧急程度
|
||||
|
||||
⭐⭐⭐⭐⭐
|
||||
|
||||
## 总线挂载多个电机后,pitch和yaw的GM6020电机出现编码器反馈值跳动
|
||||
|
||||
> 已修复,详细信息见“如何定位bug.md”
|
||||
|
||||
CAN1总线挂载5个电机,4\*3508+1\*6020,控制报文发送频率为500Hz,电机的反馈频率皆为1kHz.云台在控制时会出现突然跳动.添加到Ozone graph查看发现ECD(编码器)值在静止状态下也会出现突然抖动,并且幅度超过4000.但不会出现超过编码器反馈值范围的值.
|
||||
|
||||
### 尝试解决的方案
|
||||
|
||||
若使用单个6020电机,不会出现此问题. 曾认为是指针越界导致`motor_measure->ecd`值被修改, 需要进一步观察其他反馈值是否出现问题. 且反馈值始终在编码器范围之内.
|
||||
|
||||
### 如何复现问题
|
||||
|
||||
同时启用CAN1和CAN2,并在单条CAN总线上挂载超过5个电机.
|
||||
|
||||
### 紧急程度
|
||||
|
||||
⭐⭐⭐
|
|
@ -0,0 +1,183 @@
|
|||
# Work To be done & optimized
|
||||
|
||||
- **待完成**:不完成可能导致整车功能不完整
|
||||
- **待优化**:对已有的功能进行性能提高/模块解耦/可维护性增强
|
||||
- **待添加**:不紧急的/锦上添花的功能
|
||||
|
||||
**==标为黄色高亮的代表紧急程度高。==**
|
||||
|
||||
## assorted
|
||||
|
||||
- [ ] 由于我们读写和传递的数据结构都不大,基本不会发生读写时任务切换的情况。典型的数据读写时间都是~μs,故没有对数据访问的接口添加互斥锁或关闭全局中断。后续有需求(如大量数据复制)可以添加。可以新增一个bsp_mutex或者module层的ds,提供相应支持。实际上freertos提供了一些供线程(任务)间进行数据交互的类型和函数,请查阅对应文档。
|
||||
|
||||
最简单的防止重入或数据竞争的方式是创建一个bool类型值实现互斥访问。当一个线程或中断要访问某个变量时,先检查这个变量对应的bool锁是否为1,若不为1则赋值为1表明当前有线程访问变量,之后可以开始对该变量的操作,结束读写后释放锁即赋0。不像osSemaphore或osMessageQueue等只允许在中断中添加消息或释放信号量/互斥量,这种变量锁可以在任意处加锁解锁。
|
||||
|
||||
若锁获取失败,则直接退出,或将当前线程挂起等待下一次唤醒。最常见的情况是一个线程需要从一块数据区或缓冲区读取数据而某个中断会向这个区域写入数据,线程在读取的时候很可能会被中断打断。那么中断进入时发现该数据已经被上锁,就不会强行写入。为了保证数据的实时性,你可以选择将数据存入队列或启动一个新的任务,当锁释放时再写入数据。如果数据量较小,你不在乎开销,则可以使用freerots提供的osMessageQueue或osMessageMailbox。
|
||||
|
||||
目前,我们在bsp_dwt中添加了一个位锁,防止中断中调用DWTGetDeltaT或DWTGetTimeline函数更新DWT维护的时间时打断任务中的相同函数导致计数被重复更新,或引起错误的DWT溢出检测。
|
||||
|
||||
## BSP
|
||||
|
||||
### 待完成
|
||||
|
||||
|
||||
|
||||
### 待优化
|
||||
|
||||
#### bsp_pwm
|
||||
|
||||
- [ ] 是否允许修改预分频计数器?
|
||||
|
||||
### 待添加
|
||||
|
||||
#### bsp_iic
|
||||
|
||||
- [ ] 添加10位地址的支持
|
||||
|
||||
#### bsp_blueteetch
|
||||
|
||||
- [ ] 增加蓝牙功能,方便调试和测试
|
||||
|
||||
#### bsp_wifi
|
||||
|
||||
- [ ] 增加无线局域网功能,方便调试和测试
|
||||
|
||||
---
|
||||
|
||||
## Module
|
||||
|
||||
### 待完成
|
||||
|
||||
Unicom
|
||||
|
||||
- [ ] 为键鼠/遥控器/ps手柄/视觉上位机等各种控制器提供一套统一的接口,把发来数据转化为标准的控制数据,包括底盘速度云台角度等等
|
||||
|
||||
- [ ] 给每个模块增加调试的条件编译,并增加bsp log的输出。或直接在运行时添加log等级,输出不同的信息。
|
||||
|
||||
#### ==servo_motor==
|
||||
|
||||
舵机模块,需要预先定义90/180/360连续旋转的电机类型,并且能够设定max和min位置。
|
||||
|
||||
- [x] 编写舵机模块(待测试和优化)
|
||||
- [ ] 可能需要串口舵机的支持?
|
||||
|
||||
#### imu
|
||||
|
||||
- [ ] 完善bmi088模块和算法的交互,添加异步量测更新的SO3上的IEKF
|
||||
|
||||
> 继续使用四元数(S3)也许是一个更好的选择,改动较小且运算开销也较小。后续考虑修改一套ESKF_INS并移植到框架中。
|
||||
|
||||
#### ==master_machine==
|
||||
|
||||
- [ ] 增加IMU数据的时间戳
|
||||
- [ ] 增加加速度计数据
|
||||
- [ ] 重构seasky protocol的接口
|
||||
- [ ] 增加数据未更新的处理
|
||||
|
||||
需要一个更简单的协议以加快速度。若有必要,可能需要重新编写一个简单的调试上位机UI。
|
||||
|
||||
|
||||
### 待优化
|
||||
|
||||
#### buzzer
|
||||
|
||||
> 是否需要在module层就和**daemon**模块配合?
|
||||
|
||||
当前实现为buzzer是单独的module,若需要蜂鸣器警报的module可以自行包含buzzer.h以创建不同情况下的警报,如电机离线、堵转、遥控器离线等。
|
||||
|
||||
也许还有其他方式提醒离线和异常。
|
||||
|
||||
目前急需一个无线遥控继电器,防止机器人的急停模式失效。
|
||||
|
||||
#### BMI088
|
||||
|
||||
- [ ] 完善和SO3 IEKF的交互,增加异步任务的唤醒和数据传递(IMU中断唤起任务)
|
||||
|
||||
根据BMI088的datasheet在初始标定完成后将gyro和acc都设置为中断触发,当数据准备好时传感器会在对应的引脚输出跳变,通过EXTI捕获跳变并触发中断,在回调函数中启动SPI DMA传输。陀螺仪数据来到时进行姿态的预测即propagation,加速度计数据到来时进行量测更新(correct)。
|
||||
|
||||
也许需要找到一种更好的方式构建INS任务以方便和其他模块、应用的交互。
|
||||
|
||||
另外,若要进一步提升自瞄效果,在姿态得到更新时(陀螺仪和imu的数据到来时),需要额外的引脚连接到相机上完成硬触发采集,以获得更好的时间对齐效果,防止视觉得到的姿态数据发生漂移。目前视觉端假设姿态更新的频率是1khz(当前每次完成姿态解算都会向上位机发送当前的姿态)
|
||||
|
||||
#### remote_control
|
||||
|
||||
- [ ] 增加长按/短按检测 (是否有必要?)
|
||||
|
||||
#### message_center
|
||||
|
||||
- [ ] 增加队列剩余信息和数据时间戳的支持
|
||||
- [ ] 提供直接传递指针的接口?
|
||||
|
||||
#### can_comm
|
||||
|
||||
- [ ] 增加can_comm数据未更新的处理
|
||||
|
||||
#### controller
|
||||
|
||||
- [ ] 将PID的初始化改写为PIDRegister的形式,在controller统一分配内存.
|
||||
|
||||
#### dji_motor
|
||||
|
||||
- [ ] 增加3508和2006的开环零位校准函数
|
||||
- [ ] 为实例增加低通滤波系数变量,使不同电机有不同的配置
|
||||
|
||||
#### LKmotor
|
||||
|
||||
- [ ] 正反转标志位设置,需要修改反馈量和pid计算
|
||||
|
||||
#### HTmotor
|
||||
|
||||
- [ ] 正反转标志位设置,需要修改反馈量和pid计算
|
||||
|
||||
### 待添加
|
||||
|
||||
#### unicomm
|
||||
|
||||
- [ ] 完成初版构建
|
||||
|
||||
#### step_motor
|
||||
|
||||
- [ ] 增加步进电机模块
|
||||
|
||||
#### referee_communication
|
||||
|
||||
- [ ] 增加裁判系统多机通信功能
|
||||
|
||||
#### controller
|
||||
|
||||
- [ ] 增加扰动观测器,可能需要新增模块
|
||||
- [ ] 增加基于模型的控制器,可能需要新增模块
|
||||
|
||||
#### ws2816
|
||||
|
||||
- [ ] 通过bsp_pwm添加支持
|
||||
|
||||
---
|
||||
|
||||
## APP
|
||||
|
||||
### 待完成
|
||||
|
||||
#### all app
|
||||
|
||||
- [ ] 增加调试的条件编译,使得在没有连接其他应用时也可以假装有那些应用而正常调试运行
|
||||
|
||||
#### ==shoot==
|
||||
|
||||
- [ ] 增加卡弹检测和反转
|
||||
|
||||
### 待优化
|
||||
|
||||
#### robot_cmd
|
||||
|
||||
- [ ] 优化消息发布和接收性能(若皆为异步并在robottask中执行,实际上可以只传递指针)
|
||||
|
||||
#### gimbal
|
||||
|
||||
- [x] 增加底盘速度前馈控制
|
||||
|
||||
#### chassis
|
||||
|
||||
- [x] 根据电机的实际速度计算底盘的真实运动(轮式里程计)
|
||||
- [ ] 若为双板,根据IMU的数据对电机实际速度进行融合
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# 利用Ozone进行model-based PID tunning
|
||||
|
||||
Ozone的实时变量可视化监测(示波器)功能可以很好地帮助我们观察控制器在时域的表现,典型的有上升时间、超调量和稳态时间等。
|
||||
|
||||
## 调试顺序
|
||||
|
||||
先内环,后外环。若有已知的外部扰动如阻力、重力等可以在**保持kp不变**的情况下添加积分环节,并查看达到稳态时积分的输出,该输出值可以作为**前馈**作用通过feedforward_ptr一同送入下一个串级控制器。在没有模型的时候,计算前馈一般通过**数据驱动**的方法,如稳态误差-参考值关系拟合。
|
||||
|
||||
经典的经验式整定方法有简单的Ziegler-Nicols法和Cohen-Coon法,还有需要一定的系统辨识的Chien-Hrones-Reswick、Tyreus-Luyben和Skogestad法。这些方法在网络上或提出方法的论文中都有详尽的说明,这里不再赘述。
|
||||
|
||||
我们可以使用上述方法确定一套参数的初值,再根据时域表现进行精细的参数调整。
|
||||
|
||||
以笔者个人的纯调参无模型云台调试经验,可以进行如下步骤:
|
||||
|
||||
1. 首先整定P参数,使用二分法确定大致范围。将电机参考速度和实际速度在Ozone示波器同一窗口中打开以观察时域表现。把pid的ref值添加到变量观测,方便修改(只要修改ref值,每次就可以触发阶跃信号输入)。当P达到欠阻尼且波动只有一个周期(只有超调一个峰)时,开始添加D参数。
|
||||
2. 添加微分参数。务必打开微分滤波器,并根据你的闭环带宽(速度环要跟随的频率)设置滤波系数。目前使用的是一阶低通滤波,后续考虑增加高阶滤波器和特殊的带宽滤波器(切比雪夫、巴特沃斯等)。调节D参数至P进入临界阻尼或过阻尼的状态(没有超调)。
|
||||
3. 交替增大比例系数和微分系数,直到出现不可控的微分抖动,然后减小两者的值直到出现一个合适的平衡(调个大概即可,没有模型的情况下很难达到均衡)
|
||||
4. **固定PD参数**,查看不同目标值的**静差**。如果没有对云台进行建模,则拟合目标值与静差的关系(线性、多项式、指数、对数),并将该值作为前馈加入系统,以补偿PD无法影响的扰动项。
|
||||
5. 增加额外的积分控制以消除前馈模型不准确带来的影响。务必使用积分分离和变速积分。参数不要求精细,一般来说大致即可。
|
||||
|
||||
## model-based控制
|
||||
|
||||
无模型的控制显然存在其劣势和效果上限,为了提高性能,我们需要对云台进行建模。
|
||||
|
||||
建模的方式包括动力学方程推导和数据驱动的系统辨识。
|
||||
|
||||
动力学方程的推导即分析系统的输入(电机的扭矩)和输出(速度/角度)的关系,得到系统动态的微分方程,然后使输入等于微分方程中除输出外的项,从而让输出的动态变为简单的一阶线性常微分方程,以最快的方式到达期望位置。此时再额外增加PID控制器,用于补偿建模得到的系统和实际不匹配造成的误差。建模考虑的因素越全面,建模的效果可能会越好。
|
||||
|
||||
系统辨识的经典方法是伯德图法即频域分析。通过给定一系列的正弦输入,观察系统的输出表现得到系统的相频曲线和幅频特性曲线,并选择一个特定结构的系统对曲线进行拟合(最小二乘或极大似然估计),对得到的系统应用超前-滞后补偿控制器以确定合适的PID参数,在裕度和带宽之间权衡,使得系统的频率响应满足设计要求。
|
||||
|
||||
Ozone可以非常方便的获取系统的频率响应数据。
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
# how to locate bug in your code
|
||||
|
||||
[toc]
|
||||
|
||||
只讨论运行中的bug(指程序的运行结果不符合你的期望)和异常(直接异常终止)。编译期出现的warning和error不在此范畴,他们都可以通过直接阅读报错信息解决。
|
||||
|
||||
## Debug方法论
|
||||
|
||||
**首先**,请阅读module和bsp的标准使用示例,检查你的代码和示例是否有所不同。如果你正在编写一个新的模块,务必使用**增量式编程**的方法构建你的模块,每完成一部分的功能就进行单元测试,看看是否符合你的期望。**千万不要一口气写完**,这时候再来测试,你就无从下手了。
|
||||
|
||||
如果确认软件没有问题,先别急着单步调试,检查一下硬件连接是否正确,包括CAN的H和L,串口的TX RX以及电源和GND。 如果你的硬件有多个相同的接口但是使用不同的功能,你得好好看看是否插错接口了。 软件中对hdevice(hcan/hspi/htim等)的设定是否和CUBEMX中配置的一致? 模块的id和地址是否写错。
|
||||
|
||||
**修改之后要保存,编译,再调试/下载**。建议你把自动保存打开,并勤劳地commit。push时注意reset这些调试时产生的commit,合并成一次提交。你也可以新建一个分支用于解决bug,这是git的最佳实践。
|
||||
|
||||
同时注意条件编译的兼容,你是否测试一些应用或模块,却使用了错误的 `#define`?
|
||||
|
||||
完成上面的两步仍然无济于事,开始单步调试吧。在调试的同时,再仔细看看你的代码是否写错变量名和运算符,比如,把 `==`写成了 `=`,那么判断条件将永远是 `true`。在值得怀疑的地方,打开汇编视图,查看你要访问的地址是否正确。一步一步往下的同时,关注调用栈是否符合你的期望,添加必要的变量到调试窗口,看看他们何时发生意想不到的变化。**条件断点**是一个杀手级功能,你可以设置一些条件,让条件满足时程序在此处停下。下面的一些常见问题可能对你的调试有所帮助。
|
||||
|
||||
如果一切正常(或者应该说你没有发现异常,虽然他确实在那里),试着查看你使用的外设寄存器值。这时候你要用到芯片的数据手册和功能描述手册。在运行的每一步中,对照datasheet的寄存器状态和改变,看看是否符合你期望的程序行为。寄存器分为控制寄存器/状态就寄存器/数据寄存器,参照datasheet就可以明白这些寄存器是控制哪些功能,描述什么状态以及内部是什么数据。
|
||||
|
||||
如果你的数据是连续或规则的,记得使用Ozone可视化工具配合条件断点。
|
||||
|
||||
> 也可以让copilot帮帮你,选中你认为可能出错的代码,选择copilot brush-》debug
|
||||
|
||||
## 一些常见问题
|
||||
|
||||
### HardFault_Handler()
|
||||
|
||||
99%是由于野指针和非法内存访问导致的。在HardFault函数内添加一句 `asm("bx lr");`, 并在此处加上断点。当代码运行至此处时,选择跳出,程序会跳转回出错之前最后一句执行的语句。
|
||||
|
||||
查看你是否在出错前的最后一次操作中访问了非法地址或使用了已经被析构的指针。 `memcpy`的目标地址和源地址重合也可能引发硬件错误。另外,如果使用指针访问了一个非对齐地址(请参考__pack()相关的说明),这是CMSIS架构中不允许的(有些架构可以修改启动文件使其支持);例如你有四个uint8类型的数据被存储在0x03-0x07的地址内,这时候你通过强制类型转换,以float的方式读取这四个字节,就会发生非对齐访问。 虽然结构体可以通过 `__pack(1)`来压缩,编译器会对结构体变量进行处理,在读取非对齐字段时分别读取拆分的两个部分再进行合并,从而支持非对齐访问;但前述的行为却是未定义的,编译器在编译代码的时候并不知道你会以分开的方式访问这段内存,即使知道,他也无法预测栈上分配的空间是否能对齐。
|
||||
|
||||
常见的错误还包括使用未初始化的指针(内部可能时垃圾值,指向未知的地址)和初始化为NULL的指针(指向0x00地址)。`free`一个指针两次也可能导致错误。
|
||||
|
||||
### 通信外设传递的数据没有进行压缩
|
||||
|
||||
经典的 `__pack()`问题。这种问题大多出现在结构体的传输上。用于通信的结构体请在两端用 `#pragma __pack(1)`和 `#pragma __pack()`包裹。否则传输时会出现空字节,使得数据和你使用的协议对不上号。
|
||||
|
||||
### Delay或定时器卡死永远不跳出
|
||||
|
||||
Systick和HAL_Delay以及使用TIM来定时的方法,都需要通过**中断**来更新时间。如其重装载计数器上限为65535,当计数达到此值时会触发中断,在中断处理函数中,增加一次溢出的时间。如果此时有更高优先级的中断或同优先级的中断正在运行,且他们耗时很长 or 调用了这些依赖中断的Delay函数,那么将会形成**死锁**,永不见天日。 如果中断被关闭,这些计时也无法更新。 这里推荐使用DWT定时器(在 `bsp_dwt`中实现),其重载计数器是64位的,按照stm32f407 168MHz的运行频率,需要两天多的时间才会发生溢出,因此仅依赖其重载计数器,计算两次tick的差值就可以实现高精度的定时(除非你delay超过两天,你在搞笑)。
|
||||
|
||||
### 静态变量的陷阱
|
||||
|
||||
注意,函数内的静态变量只会在程序启动的时候初始化一次,之后不论多少次重入,都会保存上一次修改的值。
|
||||
|
||||
然而,如果静态变量被放在头文件里,则每个包含该头文件的其他源文件,都会拥有一份自己的备份,这些备份之间是互不影响的(详见编译期的头文件展开)。 千万不要认为静态变量是全局的,它只是在当前文件内有效。
|
||||
|
||||
### 指针越界读写/内存泄漏
|
||||
|
||||
有时候,你发现你使用的变量值变成了奇怪的数,或者你的程序突然崩溃了,但是你并没有在代码中对这个变量进行过修改。这时候,你应该检查一下你的指针是否越界了。 你也许没有正确的将void\*指针cast成期望的类型,使其访问了不该访问的位置;例如,一个uint8类型长度为4数组,你希望将其转化为float进行读取。但你在声明数组时只分配了3个字节,使用float\*访问就会触及未知的第四个字节,第四个位置上存放的可能是其他变量的值,这时候访问其他变量就会出现奇怪的值。 或者,你在 `memset()`和 `memcpy()`的时候没有正确设置源地址和目标地址或长度。
|
||||
|
||||
### 实时系统
|
||||
|
||||
中断中使用实时系统的接口时记得使用有 `ISR`后缀的版本,它们对中断的调用做了特殊处理。所有中断的优先级都是高于RTOS中任务的优先级的。
|
||||
|
||||
若期望某个任务以1KHz频率运行,你可能会在任务循环外加一个 `OS_Delay(1)`,但是你的任务执行时间要是超过了1ms,系统的调度就会出现异常,倘若你还在此任务内认为每次进入的时间间隔是1ms并据此编写了一些依赖周期性的代码,那便是大错特错了。
|
||||
|
||||
对于实时性和周期性要求高的任务,使用 `vTaskDelayUntil()`,这可以获得更高的定时精度。
|
||||
|
||||
不同的任务/中断调用了相同的函数,或使用了共享变量/全局变量/函数内的static变量会导致读\&写冲突,也被称作**数据竞争**。这一般只会在任务繁重且中断频率高时出现。要避免这种情况,访问共享变量时应进入临界区(关闭全局中断)或使用**互斥锁**。消息队列也是一个不错的选择,这些功能在FreeRTOS中都提供了支持。
|
||||
|
||||
### 中断
|
||||
|
||||
中断不要放入太复杂的逻辑和运算。使用标志位或将要处理的数据转移到队列中,于任务中检查标志位,判断是否要进行数据的处理。否则可能出现中断过于复杂/频繁使得通信出现overrun error
|
||||
|
||||
强烈建议初始化时不要使用和中断相关的功能,若你在中断过程中访问了一些尚未初始化的变量,就很大概率会出现前述的野指针/越界等问题。 非要使用,请添加一个标志位,并让中断判断初始化是否完成。**当前框架在初始化机器人的时候关闭了全局中断,所以千万不要使用中断和与symstick/HALtick有关的延时!**
|
||||
|
||||
### 强制类型转换
|
||||
|
||||
long long的范围比float小。无符号和有符号数直接转换可能变成负数。**应该在一切可能表达运算顺序错误的地方加上括号以明确操作的顺序,即使你知道不同运算符的优先级。** 使用移位操作要注意你的变量类型,请不要相信编译器的临时变量生成,务必加上类型转换。
|
||||
|
||||
例如:`#define MY_MACRO_NUMBER 3.0f`,使用宏定义一些带小数点的数据时记得加上.0或f后缀,干脆两个都加。无符号定义要加u后缀。
|
||||
|
||||
### 宏
|
||||
|
||||
换行用 `\` ,注意同一个代码块展开后用花括号 `{}`包裹,特别注意宏展开之后是直接的文本替换!!!
|
||||
|
||||
用已有的宏定义宏并且进行运算时,要将后面的字段用括号包围,因为:
|
||||
|
||||
```c
|
||||
#define YOUR_DEF SOMETHING
|
||||
// 宏通过空格来解析替换字段,YOUR_DEF空格后的第一个字段当作替换文本
|
||||
```
|
||||
|
||||
**宏只在当前文件生效**,如果宏放在.c那么对其他的文件是不可见的,这也一般称作私有宏。
|
||||
|
||||
## 典型debug案例一
|
||||
|
||||
这是一个结合了软件和硬件且有多模块耦合的异常。该bug发生在调试平衡步兵的底盘过程当中。
|
||||
|
||||
### 引发bug的原因
|
||||
|
||||
1. 指针在强制类型转换中变成了错误的类型,使得指向的内存地址被错误地修改
|
||||
2. CAN总线负载过大导致电机反馈消息丢失
|
||||
|
||||
这里是发生bug的代码片段:
|
||||
|
||||
```c
|
||||
static void LKMotorDecode(CANInstance *_instance)
|
||||
{
|
||||
static LKMotor_Measure_t *measure;
|
||||
static uint8_t *rx_buff;
|
||||
rx_buff = _instance->rx_buff;
|
||||
measure = &((LKMotorInstance *)_instance)->measure; // 通过caninstance保存的id获取对应的motorinstance
|
||||
// 上面一行应为: measure = &(((LKMotorInstance *)_instance->id)->measure);
|
||||
measure->last_ecd = measure->ecd;
|
||||
measure->ecd = ...
|
||||
|
||||
// ....
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
这是问题1的出处。can instance中保存了父指针,即拥有该instance的LKMotorInstance。这里想通过强制类型转换将 `void*`类型的 `id`转换成电机的instance指针类型并访问其measure成员变量以从CAN反馈的报文中更新量测值。然而却直接将can instance转换成motor instance。
|
||||
|
||||
随后,更新之后的数据被覆写到can instance内部,使得其成员变量改变,包括hcan、txbuf、rxbuf、tx/rxlen等。hcan是HAL定义的can句柄类型,里面保存了指向can状态和控制寄存器的指针以及其他HAL状态信息,然而其值被电机反馈回来的值覆写,之后HAL的接口访问hcan时将引起异常。
|
||||
|
||||
第二个问题则不是显式存在的:
|
||||
|
||||
```c
|
||||
void MotorControlTask()
|
||||
{
|
||||
DJIMotorControl();
|
||||
|
||||
HTMotorControl();
|
||||
|
||||
LKMotorControl();
|
||||
|
||||
ServeoMotorControl();
|
||||
|
||||
StepMotorControl();
|
||||
}
|
||||
```
|
||||
|
||||
这是motortask的内容,此任务将以500hz的频率运行。在发生bug时,我们将4个HT04电机和2个LK MF9025电机全部连接到CAN1上。注意,HT04不支持多电机指令,因此占用的带宽较大。在 `LKMotorControl()`完成参考值计算和CAN发送之后立刻会调用 `HTMotorControl()`,后者需要连续发送4条报文。而HT和LK电机都会在接收到控制指令之后发送反馈信息报文。由于HT电机的控制在LK电机控制之后立刻执行,导致总线被占据,LK电机发送的反馈数据仲裁失败无法获得总线占有权,使得主机收不到反馈数据。
|
||||
|
||||
### bug的发现和定位的尝试
|
||||
|
||||
程序的大体情况如下,当时进行轮足式倒立摆机器人的测试,启用了balance.c,在其中注册了4个HT04电机(can1)和2个LK9025电机(can2)。控制报文的发送频率均为500Hz。
|
||||
|
||||
测试时发现,9025电机可以接收到mcu发送的控制指令并响应,但是mcu始终无法获得反馈值,`LKMotorInstance->measure`的所有成员变量一直是零。由于CAN是总线架构,电机能接收到数据说明通信正常。HT04电机也可以正常控制并收到反馈信息。在 `LKMotorDecode()`函数中添加断点发现能够成功进入1~2次,随后便引发HardFault。
|
||||
|
||||
此时内心有些动摇,开始检查硬件连线。我们尝试把LK电机也挂载到CAN1总线上。开始单步调试,发现LK电机可以正常接收一次反馈报文,之后就进入 `Hardfault_handler()`。HT和DJI电机均无此问题。进一步进行每条指令的调试,发现在成功接收到一次报文之后(接收报文指的是can发生中断并在处理函数中调用LK电机的解码函数,我们并没有查看measure值是否刷新,实际上这时候反馈值仍然为零),进入该电机的控制报文发送时,通过在 `Hardfault_handler()`中添加汇编语句 `asm("bx lr")`,即跳转到最后一次执行的指令,发现访问 `hcan->state`会引起硬件错误。遇到这种情况,说明发生了越界访问或使用了野指针。检查hcan的值,发现是一个非常大的地址。因此怀疑hcan指针被其他的内存访问语句修改。
|
||||
|
||||
有了方向之后,进一步对每一个函数都进行单步进入调试,同时时刻监测hcan1的值。然而,这时候出现即使一开始就单步调试也无法进入LK电机解码函数的问题。于是,怀疑是CAN过滤器的配置问题,使得LK电机反馈报文被过滤,检查LK的接收id无误后,认为可能由于LK电机的发送和接收ID都比较大(0x140和0x280),CAN标准ID放不下。但是查阅CAN specification后发现standar ID可以容纳11位的值,应该不会有问题。于是把过滤器配置为mask模式,让bxCAN控制器接收所有报文(即不进行过滤)。然而还是不奏效,仍然无法收到数据。
|
||||
|
||||
这时候想起HT电机是不支持多电机控制指令的,因此500Hz的控制频率似乎有些过高,相当于2ms内要完成2x4+1+2=11次CAN报文的发送。计算1M波特率下最大通信速率,果然超出了负载。于是降低 `MotorTask()`的频率为200Hz,果然能重新接收到数据了。
|
||||
|
||||
继续单步调试,终于发现在 `LKMotorDecode()`中,通过强制类型转换获取LKMotorInstance的时候,用错了变量,使得反馈值被写入电机的 `CANInstance`内,导致hcan指向随机的地址,最终造成访问时引发hardfault。
|
||||
|
||||
修改之后,将LK电机挂载到CAN2上,控制频率回到500Hz,程序正常运行。
|
||||
|
||||
### 解决方案
|
||||
|
||||
均衡总线负载,调节任务运行时间。
|
||||
|
||||
# 典型debug案例二
|
||||
|
||||
这仍然是一个CAN总线引发的bug。使用的电机均为DJI电机。当多个电机接入时,会产生反馈值跳变的情况。起初认为**总线负载过高**,(控制频率为500Hz,反馈频率均为1kHz,计算之后得出CAN的负载率接近90%),但将电机减少为一半甚至更少时仍然出现此问题。**单独使用CAN1且仅挂载一个电机则问题消失**,同时使用CAN1和CAN2(不论单个总线挂载几个电机)则问题再次出现。
|
||||
|
||||
**单步调试发现反馈值并未因指针越界而被纂改**。仔细检查代码的计算发现并未出错,打开Ozone查看反馈值曲线,发现确实偶发跳变,但跳变值并未超出反馈值范围,即即使发生跳变值仍然在**正常范围内**,因此不像是总线负载过大导致数据帧错误或指针越界修改的随机值。加入多个电机同时查看反馈值,**发现反馈跳变之后会和另一电机的反馈值相同**,呈现“你跳到我我跳到你”的图景。怀疑CAN中断被**重入**,即一个中断未完成时另一个CAN报文到来,打断了当前的中断并执行了**相同的反馈解码函数**。但CAN1和CAN2的中断优先级均为5,因此不可能打断彼此。打开CubeMX查看初始化配置,发现两个CAN的FIFO0和FIFO1中断优先级不同,分别是5和6。则FIFO1的溢出中断会被FIFO0打断,且我们在电机的解码函数中使用了一些**静态变量**用于存储触发接收中断的电机报文的相关信息,故而新进入的中断覆写了之前中断的静态变量值,使得之前中断在恢复之后存储了前者的值,导致自身反馈错误。
|
||||
|
||||
将优先级统一设为5,编译之后重新运行,反馈值正常。
|
||||
|
||||
> “同时使用CAN1和CAN2(不论几个电机)则问题再次出现。” 导致此问题的原因是初始化CAN时按照rxid分配FIFO,因此注册的电机会被交替分配到不同的FIFO,故不论注册了几个电机(只要多于2)、注册到哪条总线都会出现FIFO1中断被FIFO0打断的情况。
|
|
@ -0,0 +1,27 @@
|
|||
# MUST & MUSTNOTMUSTNOT
|
||||
|
||||
## 禁止过度摸鱼
|
||||
|
||||
提供工作效率!
|
||||
## 禁止在临界区使用延时,这会导致因中断关闭使得定时器无法进入中断更新时间,进而卡死系统
|
||||
|
||||
除非你使用的是基于计数寄存器差值的延时方法,或阻塞式的for延时。
|
||||
**若有必要,应该使用`bsp_dwt.h`提供的接口。
|
||||
|
||||
## 若任务耗时较长导致可能出现数据读写被中断或更高优先级的任务打断,请为你的数据添加锁
|
||||
|
||||
若同时要求数据的实时性,考虑将低优先级线程设置为由高优先级任务唤醒,或添加位互斥锁(而不是osMutex!确保中断也可以使用)。
|
||||
|
||||
## 禁止图方便直接将电机/电调连接在开发板的xt30接口上,否则电机的反电动势可能烧毁开发板
|
||||
|
||||
后续考虑增加一个xt30转接器,其上实现隔离电路,再连接开发板充当分电板。
|
||||
|
||||
## 请给你编写的bsp和module提供详细的文档和使用示例,并为接口增加安全检查
|
||||
|
||||
用于调试的条件编译和(若有可能)log输出也是必须的。
|
||||
|
||||
另外,“treat your user as idot!”
|
||||
|
||||
## NO WARNING
|
||||
|
||||
makefile中已经启用了`-Werror`选项,所有的warning都会被视为error,别妄图带着warning通过编译!
|
|
@ -0,0 +1,275 @@
|
|||
# 2023 EC basic-framework
|
||||
|
||||
> 每个bsp/module/application都有对应文档,建议阅读之后再看代码&进行开发。框架的搭建思路和讲解视频戳这里:[basic_framework讲解](https://www.bilibili.com/video/BV1Bd4y1E7CN)。
|
||||
> 开发之前必看的文档:**README.md & VSCode+Ozone使用方法.md** 。开发app层请看application目录下的文档,若要开发module以及bsp务必把上层文档也浏览一遍以熟悉接口定义的方式。
|
||||
> **程序的运行流程和框架所有app/module/bsp的数据流图直接拉到本文档底部。**
|
||||
|
||||
此框架为机器人通用设计,当前的app层是为步兵设计的。不同的机器人只需要重新编写应用层。在我们的战队仓库中有英雄、工程、哨兵、平衡步兵等兵种,可作参考。
|
||||
|
||||
此框架在RoboMaster A型开发板的移植也已在组织仓库中提供。
|
||||
|
||||
[TOC]
|
||||
|
||||
## 基本信息和开发规范
|
||||
|
||||
- **开发方式**:
|
||||
|
||||
本框架使用stm32cubemx生成,基于makefile编译系统(后期拟修改为cmake+nijna+makefile以提高编译速度,对于目前的版本您可以考虑自行安装ccache以提高编译速度),使用arm gnu工具链开发,利用arm-none-eabi-gcc编译(make命令,命令行为mingw32-make)。
|
||||
|
||||
> 目前已经支持CMakeLists构建。
|
||||
|
||||
> ***==!deprecated==***:若需使用keil5开发,请在stm32cubemx的`project manager`标签页下将工具链改为MDK,然后在keil中自行添加所需包含的.c文件和头文件。关于如何在keil下添加dsplib,请参考文档。在vscode中也有**KEIL assistant**和**Embedded IDE**插件可供使用。
|
||||
>
|
||||
> ***强烈推荐使用VSCode进行开发,Ozone进行调试。***
|
||||
|
||||
VSCode可通过Cortex-Debug利用OpenOCD进行调试,jlink/stlink/dap-link都支持,具体的使用方法和环境配置教程在[VSCode+Ozone使用方法](./VSCode+Ozone使用方法.md)中。**请使用UTF-8编码查看\&编辑此项目**。
|
||||
**此外,本项目中使用到的物理变量值均采用标准单位制**,若有特殊需求,可以通过module层的`general_def.h`添加物理量转换关系的宏。
|
||||
|
||||
- **分层**:
|
||||
|
||||
本框架主要代码分为**BSP、Module、APP**三层。三层的代码分别存放在同名的三个文件夹中,这三个文件夹存放在根目录下。开发过程中主要编写APP层代码,Module层与BSP层不建议修改。如需添加module(如oled屏幕、其他传感器和外设等),请按照规范编写并联系组长提交commit到dev分支或对应的功能名分支,完善后合并至主分支。在配置git的时候,将自己的`user.name`配置成英文缩写或易懂的nick name。
|
||||
|
||||
BSP层构建于ST的HAL(硬件抽象层)之上,针对RoboMaster竞赛所用电控外设和模块的特点对其进行了进一步封装;Module层是基于bsp的封装打造的各种模块,旨在为app层提供**硬件无关的接口**,即应用层不应该出线任何与片上外设相关的代码。
|
||||
|
||||
**main.c的位置在**`Src/main.c`
|
||||
|
||||
- **代码格式**:
|
||||
|
||||
在vscode-设置-扩展-C/C++-C_Cpp:style下修改。默认为`Visual Studio`。编写完新的代码后,使用`右键-格式化`或`shift+alt+f`(请勿对cube生成的文件使用此操作否则重新生成异常)。此操作不会改变文档的内容,但会改变缩进、空行、符号位置等,使代码更加统一、整洁。
|
||||
|
||||
**在cubemx生成的文件(尤其是main.c和freertos.c)时,务必按照cubemx的提示将用户代码放在usercode注释代码块内,否则重新生成时会被覆盖.**
|
||||
|
||||
请保持良好的注释编写习惯,建议安装doxygen插件。务必统一在.h文件中为外部接口编写注释,并给类型定义编写必要的注释。对于私有函数(.c文件中static修饰),请在.c文件中进行注释。对于复杂的代码段,也请添加注释。
|
||||
|
||||
每个功能模块编写完之后,及时添加说明文档。内容参照已有的文档,要进行简短的**总体说明、代码结构、外部接口和类型定义、私有函数和变量,以及使用的说明和范例**。如果有特别需要注意的地方,也请说明。
|
||||
|
||||
==**在编写代码的时候,注意添加安全检查,“treat your users as idiots!”**==
|
||||
|
||||
- **面向对象设计**:
|
||||
|
||||
C语言不存在“成员函数”的概念。为实现类似效果,所有按照这一思想构建的函数都会有一个传入参数,将结构体(对象)传入。
|
||||
|
||||
- **代码风格:**
|
||||
|
||||
函数统一使用**动宾短语**,建议不超过4个单词。每个单词首字母大写:
|
||||
|
||||
```c
|
||||
void SetMotorControl()
|
||||
```
|
||||
|
||||
变量命名使用下划线命名法,统一小写。尽量不要使用缩写,并注意让变量名本身能够表达其含义:
|
||||
|
||||
```c
|
||||
uint8_t gimbal_recv_cmd;
|
||||
```
|
||||
|
||||
后续可能将指针类型的变量名都加上`ptr_`或`p`前缀。私有变量加上下划线`_`前缀。
|
||||
|
||||
在利用`typedef`定义新的类型时,使用单词首字母大写+下划线隔开+定义后缀的方式:
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
float Accel[3];
|
||||
float Gyro[3];
|
||||
} IMU_Data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
can_instance_config_s can_config;
|
||||
uint8_t send_data_len;
|
||||
uint8_t recv_data_len;
|
||||
} CANComm_Init_Config_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float *other_angle_feedback_ptr;
|
||||
float *other_speed_feedback_ptr;
|
||||
|
||||
PID_t current_PID;
|
||||
PID_t speed_PID;
|
||||
PID_t angle_PID;
|
||||
|
||||
float pid_ref; // 将会作为每个环的输入和输出顺次通过串级闭环
|
||||
} Motor_Controller_s;
|
||||
```
|
||||
|
||||
数据类型单一、结构不复杂的类型以`_t`后缀结尾(表明这是一种数据,type);复杂的结构体类型使用`_s`结尾,表明其功能和内涵多(structure)。对于某个bsp、module,其类型结构体应该称为`xxxInstance`:
|
||||
|
||||
```c
|
||||
typedef struct _
|
||||
{
|
||||
CAN_HandleTypeDef *can_handle; // can句柄
|
||||
CAN_TxHeaderTypeDef txconf; // CAN报文发送配置
|
||||
uint32_t tx_id; // 发送id
|
||||
uint32_t tx_mailbox; // CAN消息填入的邮箱号
|
||||
uint8_t tx_buff[8]; // 发送缓存,最大为8
|
||||
uint8_t rx_buff[8]; // 接收缓存
|
||||
uint32_t rx_id; // 接收id
|
||||
uint8_t rx_len; // 接收长度,可能为0-8
|
||||
// 接收的回调函数,用于解析接收到的数据
|
||||
void (*can_module_callback)(struct _ *); // callback needs an instance to tell among registered ones
|
||||
} CANInstance;
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他IDE支持
|
||||
|
||||
你还可以尝试VSC的EIDE插件+ozone的方式开发ac5/6工具链的程序。ac5/6工具链由于为arm出品的商业闭源软件,对mcu硬件架构的针对性优化更多,编译出来的程序优化效果往往更好、体积更小,执行速度快过arm-gnu工具链。
|
||||
|
||||
另外的可能是Visual Studio + VisualGDB,根据VisualGDB的官网进行配置即可,可以利用VS提供的各种测试调试性能分析功能。对于熟悉VS丰富的功能支持的开发者,可以选择此方式。
|
||||
|
||||
还可以尝试VSC的插件KEIL assistant,通过此法你需要在根目录打开cubeide配置文件,在project manager标签页选择将工具链改为MDK,**我们非常不推荐这种方式**。若要使用CubeIDE,也在相同的地方修改工具链。
|
||||
|
||||
***不过开发本框架的最佳实践仍然是VSCode+Ozone。***
|
||||
|
||||
> 只要你学习了[VSCode+Ozone使用方法](./VSCode+Ozone使用方法.md)文档内的*预备知识* ,掌握了工具链的用途和原理之后,不论换用什么IDE什么编译器,你都可以切换自如。
|
||||
|
||||
|
||||
|
||||
## BSP层(Board Sopport Package)
|
||||
|
||||
- 主要功能:实现对STM HAL的封装功能,进一步抽象硬件。
|
||||
- 在本框架中,BSP层与cubeMX初始化有一定程度的耦合,若没有在CUBEMX中开启某个外设,则在application不能初始化使用了对应外设的module。对该层的修改可能需要使用cube重新生成工程(主要是外设的配置,通信速度,时钟频率和分频数等)。该层也是唯一允许直接出现stm32HAL库函数的代码层,**在非BSP层编写代码时,如需使用HAL_...函数,请思考是否有同功能的BSP_...函数**。不过,由于ST的HAL已经对硬件进行较高的抽象(如以handle_xxx的方式描述一个硬件外设或功能引脚),因此即使需要更换开发板,必须修改的内容也极少。
|
||||
- 最简单的(如gpio)仅是对HAL库函数的封装。较为复杂的则会进行一定程度的处理(如can)
|
||||
|
||||
**编写和使用指南**
|
||||
|
||||
- 补充与修改:某款主控对应的BSP层应保持相同,当认为该层可能缺少部分功能或有错误时,请联系组长确认后解决并更新整个框架,**请勿自行修改提交**。 请在你修改/增加的bsp_XXX.md中提供测试用例和使用示范以及任何其他需要注意的事项,并在代码必要的地方添加注释。
|
||||
- 代码移植:BSP层也是在不同系列、型号的stm32间执行代码移植时主要需要关注的代码层。向功能更强系列移植一般只需要重配cube,而向功能较少的系列移植还需要去掉其不支持的功能。如果仅是对同一型号的开发板进行CUBEMX初始化配置的修改,一般只需要给app层的应用重新分配外设和引脚,或修改波特率和通信频率等。
|
||||
- 子文件与文件夹:
|
||||
- bsp.c/h:该层用于bsp基础功能初始化的文件,其中`bsp.h`被include至main.c中,以实现必须的底层初始化,目前需要初始化的bsp只有log和dwt,**不同主频的MCU需要修改dwt初始化的参数**。**注意**,有些外设如串口和CAN不需要在bsp.c中进行模块层的初始化,他们会在module层生成实例(即C语言中的结构体)并注册到bsp层时自动进行初始化。以此达到提高运行速度避免未使用的模块被加载的问题。
|
||||
- bsp_xxx.c/h:每一个成对的.c/h对应一种外设,当上面两个代码层需要使用某个外设时,这里的文件就是对应的交互接口。
|
||||
- 注册回调函数与接收:通信类外设模块有的定义了回调函数(函数指针类型),module层的模块需要自行处理接收回调函数,在注册bsp的时候应传入对应参数格式的回调函数指针,使得接收中断发生的时候bsp层可以自行找到对应的上层回调函数进行调用。这也是回调函数设计的初衷:为底层代码调用上层代码提供接口,当特定事件发生的时候完成触发(自行搜索hook函数)。
|
||||
|
||||
## Module层
|
||||
|
||||
- 主要功能:实现对设备的封装,如将IMU、PC、电机等视为一个完整的功能模块,让应用层(app)不需要关心其底层的具体实现,直接使用接口。
|
||||
|
||||
- 文件夹
|
||||
|
||||
- **注意,module层没有也不需要进行统一初始化**。app层的应用会包含一些模块,因此由app来调用各个模块的init()或register()函数,只有当一个module被app实例化,这个模块才会存在。
|
||||
|
||||
> ~~命名为init()的初始化一般来说是开发板的独占资源,即有且只有一个这样的模块,无法拥有多个实例,如板载陀螺仪、LED、按键等。命名为register()的模块则可以拥有多个,比如电机。~~ legacy support,为了保证代码风格统一,所有接口统一命名为xxxRegister()。
|
||||
|
||||
- algorithm:该层软件库存放位置,这些功能与硬件无关,而是提供通用的数据结构和“算子”以供该层的其他部分调用,主要是算法、控制器、底盘和位姿解算等。
|
||||
|
||||
- module编写和使用指南:
|
||||
|
||||
- 初始化:
|
||||
|
||||
根据代码对应的函数说明,传入对应的配置文件。对于某些需要集中设置的参数,一般于模块的头文件中会额外设定一个xxx_config_s的结构体用于初始化的参数传递。如果不需要进行这样的集中设置,则是直接传入对应的参数或module结构体中本就存在的成员变量。
|
||||
|
||||
- 结构体:
|
||||
|
||||
也就是所说的“实例”,定义一个module结构体,对于app层来说就是拥有某一个功能模块的实例,比如一个特定的电机。在对电机进行操作的时候,为实现面向对象的功能,需要在接口函数中传入该结构体指针。
|
||||
|
||||
- 函数:
|
||||
|
||||
.c中存放的static函数和static变量相当于这个类的private函数,.h中的则相当于public。相似的driver的public函数应较为统一。由于通信格式,使用方法等的不同,不同通信设备在读取操作、数据格式上可能有所不同,这些不同应该在driver的内部处理。**由于C语言没有对象的概念,对于通信类的module,不同的实例需要在module.c中保存一份指针,用于处理数据接收的解析。**
|
||||
|
||||
- 封装程度:
|
||||
|
||||
app层使用时与底层实现无关。如在使用电机时,这个电机的数据该和哪些电机的数据在一个数据包中发送,can的过滤器设置,均属于应该自动处理的功能;通信类的模块应该封装到只有初始化、发送和读取。对于电机,则是用于初始化的`register`和发送控制命令`set_control`两个函数和一个实时更新的用于给app层提供该信息的数据结构体(电机反馈信息)。
|
||||
|
||||
Module层主要存放的是类型定义和实例指针数组,在该层没有进行实例化(定义或通过malloc分配空间),若在APP层没有实例化,则该模块的存在与否不会影响编译后的可执行文件,只会占用.c文件中的static变量和代码区的少量内存(有些module只会保存每个实例对象的指针,在没有初始化的时候仅仅占用一个指针数组的空间)。因此,基于本框架的其他工程没有必要删除APP层未使用的module文件。
|
||||
|
||||
务必为模块添加说明文档和使用范例,以及其他需要注意的事项(如果有)。
|
||||
|
||||
> **面向对象小指南:**
|
||||
>
|
||||
> 由于C语言没有对象的概念,对于需要使用通信的module,在其.c文件下都需要保存每个实例的指针,在收到消息时(发生回调)遍历所有实例指针,找到收到消息的实例。这种处理方式可能会导致实时性下降,例如CAN接收时要遍历所有注册了CAN的实例,进入module层还需要一次遍历。用C++则可以将对象的this指针和模块的回调函数进行绑定,生成一个可调用对象然后再进行CAN的注册,使得其不需要module层的遍历。
|
||||
>
|
||||
> 考虑在实例中加入一个额外的`void*`域成员(成员变量),其内容为module层实例的地址。这样CAN收到消息时只需要遍历所有CAN instance,对于相同的模块,可以在其回调函数内部获取CAN instance的`void*`指针并通过强制类型转换cast成模块的实例结构体指针类型,从而访问特定的模块。
|
||||
> 这实际上是保存“对象”的parent pointer,使得实例可以访问拥有自己的实例(访问自己的父亲)。和回调函数配合,就可以防止交叉包含并为底层访问上层内容提供支持。
|
||||
|
||||
## APP层(application)
|
||||
|
||||
- 功能:实现机器人的控制,对机器人**控制**结构进行抽象。
|
||||
|
||||
在完成BSP层和Module层后,如果在APP层没有控制代码,则代码并无实际功能。换言之,BSP层与Module层的存在是为了APP层更简单、更合理、更易于扩展和移植。本框架的初始目标即是实现:在APP层仅需思考逻辑并用无关硬件的C语言代码实现即可完成整个机器人的控制。所有需要使用的模块和算法都在Module层提供,开发板外设硬件的抽象在bsp层完成。**所有使用到的模块都在APP层初始化**,因此不需要module自行初始化。
|
||||
|
||||
- APP层按照机械设计结构(如云台、发射、底盘、夹爪、抬升、机械臂)建立对应的子文件夹,在其中完成初始化和相关逻辑功能的编写。还有用于发布指令的云台指令应用和底盘指令应用,前者应该包含一个遥控器模块和一个视觉通信模块,后者包含裁判系统模块。它们包含的模块都会处理一些指令和控制信息,这样还可以方便兼容双板。
|
||||
|
||||
- 单双板切换在application的`robot_def.h`中进行,**修改宏定义可以切换开发板的设定模式**。当设定为单板的时候,在`robot.c`中会对gimbal,chassis,shoot,robot_cmd四个应用都进行初始化。对于双板的情况,需要将上板配置为gimbal board,下板配置为chassis board,它们会分别初始化gimbal/shoot/robot_cmd和chassis
|
||||
|
||||
- 对于单板的情况,所有应用之间的信息交互通过message center完成。而使用双板时,需要通过板间通信传递控制信息(默认遥控器接收机和pc在云台板,裁判系统在底盘板,因此需要互发信息)。当前通过**条件编译**来控制信息的去向(发往message center/接收,还是通过can comm发送/接收),后续考虑将双板通信纳入message center的实现中,根据`robot_def.h`的开发板定义自动处理通信,降低应用层级的逻辑复杂度。
|
||||
|
||||
## 文件树
|
||||
|
||||
板级支持包的每个组件,每个moduel,以及每个app都有对应的说明文档.
|
||||
|
||||
```shell
|
||||
ROOT:.
|
||||
│ .gitignore # git版本管理忽略文件
|
||||
│ .mxproject # CubeMX项目文件
|
||||
│ basic_framework.ioc # CubeMX初始化配置文件
|
||||
│ debug_ozone.jdebug # ozone debug调试配置和缓存文件
|
||||
│ LICENSE # 开源协议文件
|
||||
│ Makefile # 编译管理文件,为make(mingw32-make)命令的目标
|
||||
| Makefile.upgrade # 编译管理文件的升级版, 资深用户使用
|
||||
| CMakeLists.txt # cmake构建规则, 资深用户使用
|
||||
│ openocd_dap.cfg # 用于OpenOCD调试使用的配置文件,dap用
|
||||
│ openocd_jlink.cfg # 用于OpenOCD调试使用的配置文件,jlink用
|
||||
│ README.md # 本说明文档
|
||||
│ startup_stm32f407xx.s # F407汇编启动文件
|
||||
│ stm32.jflash # jlink的烧录的配置文件,一键下载用
|
||||
│ STM32F407.svd # F407外设地址映射文件,用于调试
|
||||
│ STM32F407IGHx_FLASH.ld # F407IGH(C板MCU)目标FLASH地址和链接规则,用于编译(作为链接阶段的链接器)
|
||||
│ task.ps1 # powershell脚本,一键编译并进入ozone调试/reset开发板用
|
||||
│
|
||||
├─.vscode
|
||||
│ launch.json # 调试的配置文件
|
||||
│ settings.json # 工作区配置文件,根据自己的需要配置
|
||||
│ tasks.json # 任务配置文件,包括一键编译下载调试等
|
||||
│
|
||||
├─.assets # 说明文档的图片
|
||||
├─.Doc # 本框架的各类说明文档
|
||||
├─.github # github action CI支持文件
|
||||
│
|
||||
├─application # 应用层
|
||||
├─bsp # 板级支持包
|
||||
├─modules # 模块层
|
||||
│
|
||||
├─Src # hal生成的外设初始化源文件
|
||||
├─Inc # hal生成的外设初始化头文件
|
||||
├─Drivers # hal driver和cmsis drivers
|
||||
└─Middlewares # STusb ext, rtos, segger rtt等
|
||||
```
|
||||
|
||||
## BSP/Module/Application介绍
|
||||
|
||||
在对应应用、模块和板级支持包文件夹下。每个.c文件或完整的功能模块都有说明文档。在编写新代码时注意按照规范编写说明文档。
|
||||
|
||||
## 整体架构
|
||||
|
||||
### 软件分层
|
||||
|
||||
<img src="../.assets/image-20230725153133419.png" style="zoom:67%;" />
|
||||
|
||||
### 运行任务
|
||||
|
||||
<img src="../.assets/image-20230725152433502.png" style="zoom: 50%;" />
|
||||
|
||||
### 初始化流程
|
||||
|
||||
~~~mermaid
|
||||
graph TD
|
||||
HAL库初始化 --> BSP初始化 --> Application初始化 --> app调用其拥有模块的初始化 --> 启动操作系统
|
||||
~~~
|
||||
|
||||
**注意,应用初始化不得放入其对应任务中,即使是在死循环前,否则可能导致一些需要定时器的任务初始化异常**。
|
||||
|
||||
APP会调用其所有的模块的初始化函数(注册函数),这是因为本框架的设计思想是任何模块在被注册(构造/初始化)之前,都是不存在的,当且仅当定义了一个模块结构体(也称实例)的时候,才有一个实体的概念。
|
||||
|
||||
main函数唯一需要的函数是app层的`robot.c`中的`RobotInit()`函数,它首先会调用BSP初始化,然后进行所有应用的初始化;每个应用会调用对应模块的初始化;一些依赖通信外设的模块会将通信支持相关的bsp进行初始化。初始化结束之后实时系统启动。
|
||||
|
||||
### 程序运行流程
|
||||
|
||||
![](../.assets/image-20230725153635454.png)
|
||||
|
||||
### 程序数据流
|
||||
|
||||
![](../.assets/dataflow.svg)
|
|
@ -0,0 +1,136 @@
|
|||
# 让VSCode变成你熟悉的形状
|
||||
|
||||
VSCode的各种配置如快捷键、高亮颜色、主题、界面形状和位置等(也包括各种插件的设置)可以通过在`ctrl+,`打开的设置页面修改,更好的方式是你已经尝试过的——通过xxx.json文件进行配置。VSCode的配置系统同样通过`.json`文件完成,且存在继承和覆盖的关系。VSCode的底层配置`setting.json`是针对整个VSCode进行设置的,而工作区目录下创建的`.vscode/setting.json`则可以覆盖底层配置。了解了基本的配置结构后,这里将介绍一些入手必备的设置和推荐安装的插件。
|
||||
|
||||
[TOC]
|
||||
|
||||
## 快捷键
|
||||
|
||||
不管使用什么软件,基本的快捷键一定可以帮助你提高效率,更专注于当前正在做的事——减少双手离开主键盘区的频率和时间。
|
||||
|
||||
常用的快捷键已经在[VSCode的基础操作](VSCode+Ozone使用方法.md)中介绍,这里推荐一些shortcuts的组合,可以直接`ctrl+k&s`打开快捷键设置或进入`setting.json`手动修改。当然,你不一定要和我们的建议完全一致,**根据自己的习惯定制才是最好的!**
|
||||
|
||||
- `ctrl+;`设置为移动到行尾,同时保留`end`,这样在输完函数参数之后不用按`→`或使用鼠标
|
||||
- `alt+j/k`设置为向左向右移动,这样在修改的时候不用按方向键;可以设置组合键达到”移动到符号末尾”的功能实现按符号或单词移动
|
||||
- `tab`改为移动到下一个建议(智能提示),`enter`设置为接受当前建议。如果只有一个建议,`tab`直接接受;`alt+tab`移动到上一个建议。
|
||||
- 设置一个组合键用于选中当前单词
|
||||
- 记住当前文件查找和全局查找的组合,最好再学习一下**正则表达式**。还有”选中当前所有出现“,可以快速定位当前文件有哪些地方用了这个变量/函数。
|
||||
- 熟练使用`ctrl+tab`切换当前已经打开的文件
|
||||
- 可以在`setting.json`中将`task.json`中的任务绑定成你需要的快捷键,比如默认`ctrl+shift+b`是构建任务。把一些常用的命令行操作写成task,通过快捷键瞬间触发。
|
||||
- 善用右键菜单中的peek xxx功能、展开调用层级和头文件/源文件跳转,以及git查看文件差异的功能,这在理清代码结构、查看之前的更改的时候非常有用。当然,不是让你按右键,是使用快捷键。如果你的键盘上有一个像文件一样的图标,当你聚焦在编辑区的时候可以按下它来替代右键(展开菜单)。
|
||||
- more...
|
||||
|
||||
*若你使用触控板和笔记本电脑,也可以利用触控板实现一些实在找不到的快捷键功能。*一开始你可能会决定快捷键难记又难按,当你熟练之后,却会在无形之中极大提升你的效率。
|
||||
|
||||
|
||||
|
||||
## 代码高亮
|
||||
|
||||
虽然VSCode默认的语法高亮已经吊打KEIL和CubeIDE之流,但你是否发现变量全是浅蓝色,字符串、数值字面量内部也无法区分?无出其右,我们可以自定义各种entity的颜色!
|
||||
|
||||
建议让copilot协助你完成,打开`setting.json`开始设置吧:
|
||||
|
||||
- global、private member、public member、local设置为不同的颜色
|
||||
- 私有函数和公开函数设置为不同的颜色
|
||||
- static函数设置特殊的颜色?
|
||||
- 函数参数变量设置不同的颜色?
|
||||
|
||||
|
||||
|
||||
## 终端工具
|
||||
|
||||
你至少应该学习bash(msys2中会集成一套类linux的bash工具)的基础指令,如果有可能,也学习一下powershell。在chatGPT或者Copilot的帮助下,这易如反掌。当它们无能为力时请务必查阅**官方文档**,而不是在CSDN中💩里淘🪙。
|
||||
|
||||
为你的终端配置好看的颜色、字体和背景,但不要花太多时间。一定要让你的终端具有补全和历史记录记忆功能。
|
||||
|
||||
学会在命令行中使用一些常用的git操作,虽然vscode中已经提供了强大的图形化集成。
|
||||
|
||||
务必学习vi/vim/nano的基础操作。
|
||||
|
||||
熟悉在终端中创建/追加/移动/复制/删除文件和文件夹。
|
||||
|
||||
学习gnu工具链的简单指令,协助你与编译报错信息一起定位bug和错误(常常是undefined reference或未定义函数、未定义就使用)。
|
||||
|
||||
也许,了解一下shell的工作原理,或者更多,现代操作系统的运行架构?
|
||||
|
||||
> 为basic_framework通过串口/SWD建立一套简单的cmd?有很多开源代码的实现,期待你的PR!
|
||||
|
||||
|
||||
|
||||
## 进一步提高效率
|
||||
|
||||
首先,快捷键一定要按的顺手,最好能让双手处于标准指法的起始状态就可以轻松触发。一定不要超过三个键,否则按起来手掌大开大合。
|
||||
|
||||
建议打开函数的自动括号补全(一般在对应语言的插件设置中寻找),同时习惯snippets的使用,并根据自己的需要自定义一些方便的snippets。
|
||||
|
||||
如果你认为vim很酷,那它确实很酷。vscode中有fake-vim插件,喜欢折腾的话,vim会让你在双手始终保持在键盘区,劈里啪啦地编码,只不过学习成本较高,曲线复杂。
|
||||
|
||||
你最好升级一下默认的shell,windows下有好看的posh,linux则有广为流传的zsh。具体如何配置,自行查阅**官方文档**。
|
||||
|
||||
记住,最好将不同软件开发使用的环境隔离开,所以你需要把msys2集成到vscode中!(macOS和linux用户忽略)
|
||||
|
||||
把开发中常用但又繁琐的流程自动化,积累一套你自己的脚本库。
|
||||
|
||||
....
|
||||
|
||||
|
||||
|
||||
## 插件
|
||||
|
||||
> 学习一个插件的使用,最好的方式是阅读插件的wiki和说明文档,而不是在搜索引擎里面搜索!询问ChatGPT或者Copilot Chat也是一个比较好的办法,初级的问题它们几乎不会犯错。
|
||||
|
||||
- **Better C++ Syntax**
|
||||
|
||||
用于静态解析C++代码,为intellisense以及language server提供代码高亮和完整的智能提示选项。
|
||||
|
||||
- **Blockman**
|
||||
|
||||
为代码分块。不同的作用域会被浅色背景边框包围,同时高亮当前focus的代码块,方便在大段代码中定位程序控制流。
|
||||
|
||||
- **Bookmarks**
|
||||
|
||||
为代码添加书签,可以在左侧tab页中跳转到对应位置,方便阅读代码时往复查看,也有助于阅读理解。右键点击代码行号左侧(即打断点的地方)可以添加书签或带label的书签。
|
||||
|
||||
- **C/C++ Snippets**
|
||||
|
||||
为基本的语句(关键字)提供代码补全,如输入`for`自动生成下面的代码:
|
||||
|
||||
```c
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
/* code */
|
||||
}
|
||||
```
|
||||
|
||||
补全之后,按下tab会进入不同的位置,方便进一步修改snippet。你也可以在VSCode中自定义常用的snippet补全。
|
||||
|
||||
- **Code Issue Manager**
|
||||
|
||||
可以在代码的任意地方插入“便签”和“评注”,支持多人协作。是一个比注释更好的TODO list和注意事项提醒。插入的issue支持markdown格式。
|
||||
|
||||
- **Doxygen Documention Generator**
|
||||
|
||||
为你的代码生成doxygen文档格式的注释。同时也支持一些基本的注释块生成。输入`/**`再按下回车会根据当前注释的位置自动生成合适的注释块。本框架中的注释均通过该插件生成。
|
||||
|
||||
- **Github Copilot / Copilot Labs / Copilot Chat**
|
||||
|
||||
体验大模型的威力。尤其是Copilot Chat非常适合为你提供一门语言的入门级咨询。
|
||||
|
||||
- **Gitlens**
|
||||
|
||||
方便地通过图形化的方式管理你的git仓库。
|
||||
|
||||
- **HexEditor & Hex Hover Converter**
|
||||
|
||||
以十六进制编辑文件 & 鼠标悬停在任意数值类型上时自动提供2/8/16进制的转换。
|
||||
|
||||
- **Live Share**
|
||||
|
||||
和你的伙伴一起coding。
|
||||
|
||||
- **SonarLint**
|
||||
|
||||
VSCode上最强大的静态检查工具,在VSCode自动静态检查的基础上提供更严格的代码建议,尽可能降低出错的可能。其中也包含了不同语言的最佳实践。
|
||||
|
||||
cmake可以通过添加`DCMAKE_EXPORT_COMPILE_COMMANDS=True` 的指令(直接在cmakelists中通过`set()`设定也可以),makefile则通过Makefile Tools插件设置生成`compile_commands.json`的路径。
|
||||
|
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 332 KiB |
After Width: | Height: | Size: 8.1 MiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 8.7 MiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 152 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 201 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 196 KiB |
After Width: | Height: | Size: 21 MiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 224 KiB |
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,25 @@
|
|||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
- run: arm-none-eabi-gcc --version
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- name: make
|
||||
run: make -j12
|
||||
|
||||
- uses: seanmiddleditch/gha-setup-ninja@master
|
||||
- name: ninja
|
||||
run: cd build && cmake -G Ninja .. && ninja
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
build
|
||||
./idea
|
||||
.vscode/.cortex-debug.peripherals.state.json
|
||||
.vscode/.cortex-debug.registers.state.json
|
||||
*.jdebug*
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "windows-gcc-arm",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
// 启动调试的快捷键是F5
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
// 使用dap-link(如无线调试器时的参考配置)
|
||||
{
|
||||
"name": "DAPlink",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"executable": "${workspaceRoot}\\build\\basic_framework.elf", // 要下载到调试器的文件,花括号中的是vscode两个预定义的参数
|
||||
"request": "launch",
|
||||
"type": "cortex-debug",
|
||||
//使用J-link GDB Server时必须;其他GBD Server时可选(有可能帮助自动选择SVD文件)
|
||||
//支持的设备见 https://www.segger.com/downloads/supported-devices.php
|
||||
"device": "STM32F407IG",
|
||||
//svd文件,有这个文件才能查看寄存器的值,每个单片机都不同。可以在以下地址找到 https://github.com/posborne/cmsis-svd
|
||||
//该项目的根目录已经提供了C型开发板使用的外设svd文件
|
||||
"svdFile": "STM32F407.svd",
|
||||
"servertype": "openocd", //使用的GDB Server
|
||||
"configFiles": [
|
||||
"openocd_dap.cfg", // 配置文件已经在根目录提供,若要修改以此类推,openocd的路径下的share/scripts中有各种写好的配置文件
|
||||
],
|
||||
"runToEntryPoint": "main", // 调试时在main函数入口停下
|
||||
"rtos": "FreeRTOS",
|
||||
//"preLaunchTask": "build task",//先运行Build任务编译项目,取消注释即可使用
|
||||
// dap若要使用log,请使用Jlink调试任务启动,之后再打开log任务
|
||||
// 若想要在调试前编译并且打开log,可只使用log的prelaunch task并为log任务添加depends on依赖
|
||||
},
|
||||
// 使用j-link进行调试时的参考配置
|
||||
{
|
||||
"name": "Jlink",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"executable": "${workspaceRoot}\\build\\basic_framework.elf",
|
||||
"request": "launch",
|
||||
"type": "cortex-debug",
|
||||
"device": "STM32F407IG",
|
||||
"runToEntryPoint": "main",
|
||||
"showDevDebugOutput": "none",
|
||||
"servertype": "jlink",
|
||||
"interface": "swd",
|
||||
"svdFile": "STM32F407.svd",
|
||||
"rtos": "FreeRTOS",
|
||||
// "preLaunchTask": "build task",//先运行Build任务,取消注释即可使用
|
||||
//"preLaunchTask": "log", // 调试时同时开启RTT viewer窗口,若daplink使用jlinkGDBserver启动,需要先开始调试再打开log
|
||||
// 若想要在调试前编译并且打开log,可只使用log的prelaunch task并为log任务添加depends on依赖
|
||||
},
|
||||
{
|
||||
"name": "DAP-attach",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"executable": "${workspaceRoot}\\build\\basic_framework.elf", // 要下载到调试器的文件,花括号中的是vscode两个预定义的参数
|
||||
"request": "attach",
|
||||
"type": "cortex-debug",
|
||||
"device": "STM32F407IG",
|
||||
"svdFile": "STM32F407.svd",
|
||||
"servertype": "openocd",
|
||||
"configFiles": [
|
||||
"openocd_dap.cfg",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Jlink-attach",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"executable": "${workspaceRoot}\\build\\basic_framework.elf",
|
||||
"request": "attach",
|
||||
"type": "cortex-debug",
|
||||
"device": "STM32F407IG",
|
||||
"showDevDebugOutput": "none",
|
||||
"servertype": "jlink",
|
||||
"interface": "swd",
|
||||
"svdFile": "STM32F407.svd",
|
||||
"rtos": "FreeRTOS",
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"robot_def.h": "c",
|
||||
"bsp_dwt.h": "c",
|
||||
"dji_motor.h": "c",
|
||||
"message_center.h": "c",
|
||||
"super_cap.h": "c",
|
||||
"can_comm.h": "c",
|
||||
"lqr.h": "c",
|
||||
"math.h": "c",
|
||||
"stdint.h": "c",
|
||||
"general_def.h": "c",
|
||||
"lk9025.h": "c",
|
||||
"arm_math.h": "c",
|
||||
"bmi088driver.h": "c",
|
||||
"bmi088middleware.h": "c",
|
||||
"bmi088_regndef.h": "c",
|
||||
"bmi088reg.h": "c",
|
||||
"balance.h": "c",
|
||||
"stdlib.h": "c",
|
||||
"memory.h": "c",
|
||||
"bsp_usart.h": "c",
|
||||
"compare": "c",
|
||||
"limits": "c",
|
||||
"*.tcc": "c",
|
||||
"type_traits": "c",
|
||||
"bsp_log.h": "c",
|
||||
"segger_rtt.h": "c",
|
||||
"referee.h": "c",
|
||||
"referee_communication.h": "c",
|
||||
"vmc_project.h": "c",
|
||||
"user_lib.h": "c",
|
||||
"quaternionekf.h": "c",
|
||||
"bsp_usb.h": "c",
|
||||
"robot.h": "c",
|
||||
"rm_referee.h": "c",
|
||||
"stdio.h": "c",
|
||||
"crc.h": "c",
|
||||
"bmi088.h": "c",
|
||||
"cmath": "c",
|
||||
"ht04.h": "c",
|
||||
"gain_table.h": "c",
|
||||
"referee_task.h": "c",
|
||||
"task.h": "c",
|
||||
"robot_task.h": "c",
|
||||
"motor_task.h": "c",
|
||||
"bsp_flash.h": "c",
|
||||
"bsp_iic.h": "c",
|
||||
"usbd_cdc_if.h": "c",
|
||||
"kf.h": "c",
|
||||
"none.h": "c",
|
||||
"buzzer.h": "c",
|
||||
"bsp_pwm.h": "c",
|
||||
"main.h": "c",
|
||||
"stm32f4xx_hal_conf.h": "c",
|
||||
"master_process.h": "c",
|
||||
"bsp_can.h": "c",
|
||||
"can.h": "c"
|
||||
},
|
||||
"cortex-debug.variableUseNaturalFormat": true,
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
|
||||
// "C_Cpp.default.compilerPath": "D:\\Msys2\\mingw64\\bin\\arm-none-eabi-gcc.exe"
|
||||
"makefile.compileCommandsPath": "build/compile_commands.json"
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build task", // 任务标签
|
||||
"type": "shell", // 任务类型,因为要调用mingw32-make,是在终端(CMD)里运行的,所以是shell任务
|
||||
"command": "mingw32-make -j24",// 任务命令,线程数可以根据自己的电脑修改,建议与cpu核数相同
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "download dap",
|
||||
"type": "shell", // 如果希望在下载前编译,可以把command换成下面的命令
|
||||
"command":"mingw32-make download_dap", // "mingw32-make -j24 ; mingw32-make download_dap",
|
||||
"group": { // 如果没有修改代码,编译任务不会消耗时间,因此推荐使用上面的替换.
|
||||
"kind": "build",
|
||||
"isDefault": false,
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": "download jlink", // 要使用此任务,需添加jlink的环境变量
|
||||
"type": "shell",
|
||||
"command":"mingw32-make download_jlink", // "mingw32-make -j24 ; mingw32-make download_dap"
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false,
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "log",
|
||||
"type": "shell",
|
||||
"command":"JlinkRTTClient",
|
||||
"args": [],
|
||||
"problemMatcher": [],
|
||||
// "dependsOn":[
|
||||
// "build task", // 可以添加多个.
|
||||
// ]
|
||||
// 若使用daplink,则将log任务设置为依赖于jlink launch任务,保证jlink launch任务先于log任务执行
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
# 指定编译平台/架构与语言标准, 推荐指定Ninja为构建工具,可以加快编译速度(相比make)
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
# 指定工具链
|
||||
set(CMAKE_C_COMPILER_FORCED TRUE) # skip compiler test
|
||||
set(CMAKE_CXX_COMPILER_FORCED TRUE)
|
||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
|
||||
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
|
||||
set(SIZE arm-none-eabi-size)
|
||||
set(CMAKE_AR arm-none-eabi-ar)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# 指定工程名称和语言类型
|
||||
project(basic_framework C ASM)
|
||||
|
||||
# 选择构建类型
|
||||
set(CMAKE_BUILD_TYPE Debug) # Debug Release RelWithDebInfo MinSizeRel
|
||||
|
||||
# board specific settings, arch/fpu/instruction
|
||||
set(MCU_FLAGS -mcpu=cortex-m4 -mthumb -mthumb-interwork -mfloat-abi=hard -mfpu=fpv4-sp-d16)
|
||||
set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/STM32F407IGHx_FLASH.ld") # 指定链接脚本
|
||||
set(DSP_NAME "libCMSISDSP.a") # 指定DSP库名称
|
||||
link_directories(${CMAKE_SOURCE_DIR}/Middlewares/ST/ARM/DSP/Lib)
|
||||
|
||||
# Generic compiler settings for optimization and basic link lib
|
||||
add_compile_options(-pipe ${MCU_FLAGS} -Wall -Werror -fmessage-length=0 # basic options
|
||||
-ffunction-sections -fdata-sections -fno-common # optimize options
|
||||
)
|
||||
add_link_options(-pipe ${MCU_FLAGS} -T${LINKER_SCRIPT} -Wl,--no-warn-rwx-segments # close RWX warning
|
||||
-lm -lc -lnosys # lib options
|
||||
-Wl,--gc-sections -flto -specs=nano.specs -specs=nosys.specs # optimize options
|
||||
-Wl,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map -Wl,--cref -Wl,--print-memory-usage # map options
|
||||
) # if your executable is too large , try option '-s' to strip symbols
|
||||
|
||||
# add_compile_definitions() works for compile stage
|
||||
# while add_definitions() works for both compile and link stage
|
||||
add_definitions(
|
||||
-DUSE_HAL_DRIVER
|
||||
-DSTM32F407xx
|
||||
-DARM_MATH_CM4
|
||||
) # need -D<macro> to define macro
|
||||
|
||||
# add inc
|
||||
# 递归包含头文件的函数
|
||||
function(include_sub_directories_recursively root_dir)
|
||||
if (IS_DIRECTORY ${root_dir}) # 当前路径是一个目录吗,是的话就加入到包含目录
|
||||
message("include dir: " ${root_dir})
|
||||
include_directories(${root_dir})
|
||||
endif()
|
||||
|
||||
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*) # 获得当前目录下的所有文件,让如ALL_SUB列表中
|
||||
foreach(sub ${ALL_SUB})
|
||||
if (IS_DIRECTORY ${root_dir}/${sub})
|
||||
include_sub_directories_recursively(${root_dir}/${sub}) # 对子目录递归调用,包含
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/Drivers)
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/Middlewares)
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/bsp)
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/modules)
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/application)
|
||||
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/Inc)
|
||||
|
||||
# add source, only surfix .c
|
||||
file(GLOB_RECURSE SOURCES
|
||||
"Drivers/*.c"
|
||||
"Src/*.c"
|
||||
"Middlewares/*.c"
|
||||
"bsp/*.c"
|
||||
"modules/*.c"
|
||||
"application/*.c"
|
||||
)
|
||||
|
||||
# 汇编文件路径
|
||||
# ENABLE_LANGUAGE(ASM)
|
||||
set(ASM_SOURCES
|
||||
startup_stm32f407xx.s
|
||||
Middlewares/Third_Party/SEGGER/RTT/SEGGER_RTT_ASM_ARMv7M.s
|
||||
)
|
||||
set_source_files_properties(${ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")
|
||||
|
||||
# Build types
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
message(STATUS "Maximum optimization for speed")
|
||||
add_compile_options(-Ofast)
|
||||
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
||||
message(STATUS "Maximum optimization for speed, debug info included")
|
||||
add_compile_options(-Ofast -g)
|
||||
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
|
||||
message(STATUS "Maximum optimization for size")
|
||||
add_compile_options(-Os)
|
||||
else ()
|
||||
message(STATUS "Minimal optimization, debug info included")
|
||||
add_compile_options(-Og -g -gdwarf-2)
|
||||
add_definitions(-DESC_DEBUG) # ESC Debug
|
||||
endif ()
|
||||
|
||||
# build binary and hex file
|
||||
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${ASM_SOURCES} ${LINKER_SCRIPT})
|
||||
target_link_libraries(${PROJECT_NAME}.elf ${DSP_NAME} m) # link DSP lib and math lib
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME}.elf POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex
|
||||
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin
|
||||
COMMENT "Building hex & bin file..."
|
||||
COMMENT "EXCUTABLE SIZE:"
|
||||
COMMAND ${SIZE} ${PROJECT_NAME}.elf
|
||||
)
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS STM32F4xx Device Peripheral Access Layer Header File.
|
||||
*
|
||||
* The file is the unique include file that the application programmer
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32F4xx device used in the target application
|
||||
* - To use or not the peripheral's drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral's registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f4xx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __STM32F4xx_H
|
||||
#define __STM32F4xx_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup Library_configuration_section
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief STM32 Family
|
||||
*/
|
||||
#if !defined (STM32F4)
|
||||
#define STM32F4
|
||||
#endif /* STM32F4 */
|
||||
|
||||
/* Uncomment the line below according to the target STM32 device used in your
|
||||
application
|
||||
*/
|
||||
#if !defined (STM32F405xx) && !defined (STM32F415xx) && !defined (STM32F407xx) && !defined (STM32F417xx) && \
|
||||
!defined (STM32F427xx) && !defined (STM32F437xx) && !defined (STM32F429xx) && !defined (STM32F439xx) && \
|
||||
!defined (STM32F401xC) && !defined (STM32F401xE) && !defined (STM32F410Tx) && !defined (STM32F410Cx) && \
|
||||
!defined (STM32F410Rx) && !defined (STM32F411xE) && !defined (STM32F446xx) && !defined (STM32F469xx) && \
|
||||
!defined (STM32F479xx) && !defined (STM32F412Cx) && !defined (STM32F412Rx) && !defined (STM32F412Vx) && \
|
||||
!defined (STM32F412Zx) && !defined (STM32F413xx) && !defined (STM32F423xx)
|
||||
/* #define STM32F405xx */ /*!< STM32F405RG, STM32F405VG and STM32F405ZG Devices */
|
||||
/* #define STM32F415xx */ /*!< STM32F415RG, STM32F415VG and STM32F415ZG Devices */
|
||||
/* #define STM32F407xx */ /*!< STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG and STM32F407IE Devices */
|
||||
/* #define STM32F417xx */ /*!< STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */
|
||||
/* #define STM32F427xx */ /*!< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG and STM32F427II Devices */
|
||||
/* #define STM32F437xx */ /*!< STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG and STM32F437II Devices */
|
||||
/* #define STM32F429xx */ /*!< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI, STM32F429NG,
|
||||
STM32F439NI, STM32F429IG and STM32F429II Devices */
|
||||
/* #define STM32F439xx */ /*!< STM32F439VG, STM32F439VI, STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG,
|
||||
STM32F439NI, STM32F439IG and STM32F439II Devices */
|
||||
/* #define STM32F401xC */ /*!< STM32F401CB, STM32F401CC, STM32F401RB, STM32F401RC, STM32F401VB and STM32F401VC Devices */
|
||||
/* #define STM32F401xE */ /*!< STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CE, STM32F401RE and STM32F401VE Devices */
|
||||
/* #define STM32F410Tx */ /*!< STM32F410T8 and STM32F410TB Devices */
|
||||
/* #define STM32F410Cx */ /*!< STM32F410C8 and STM32F410CB Devices */
|
||||
/* #define STM32F410Rx */ /*!< STM32F410R8 and STM32F410RB Devices */
|
||||
/* #define STM32F411xE */ /*!< STM32F411CC, STM32F411RC, STM32F411VC, STM32F411CE, STM32F411RE and STM32F411VE Devices */
|
||||
/* #define STM32F446xx */ /*!< STM32F446MC, STM32F446ME, STM32F446RC, STM32F446RE, STM32F446VC, STM32F446VE, STM32F446ZC,
|
||||
and STM32F446ZE Devices */
|
||||
/* #define STM32F469xx */ /*!< STM32F469AI, STM32F469II, STM32F469BI, STM32F469NI, STM32F469AG, STM32F469IG, STM32F469BG,
|
||||
STM32F469NG, STM32F469AE, STM32F469IE, STM32F469BE and STM32F469NE Devices */
|
||||
/* #define STM32F479xx */ /*!< STM32F479AI, STM32F479II, STM32F479BI, STM32F479NI, STM32F479AG, STM32F479IG, STM32F479BG
|
||||
and STM32F479NG Devices */
|
||||
/* #define STM32F412Cx */ /*!< STM32F412CEU and STM32F412CGU Devices */
|
||||
/* #define STM32F412Zx */ /*!< STM32F412ZET, STM32F412ZGT, STM32F412ZEJ and STM32F412ZGJ Devices */
|
||||
/* #define STM32F412Vx */ /*!< STM32F412VET, STM32F412VGT, STM32F412VEH and STM32F412VGH Devices */
|
||||
/* #define STM32F412Rx */ /*!< STM32F412RET, STM32F412RGT, STM32F412REY and STM32F412RGY Devices */
|
||||
/* #define STM32F413xx */ /*!< STM32F413CH, STM32F413MH, STM32F413RH, STM32F413VH, STM32F413ZH, STM32F413CG, STM32F413MG,
|
||||
STM32F413RG, STM32F413VG and STM32F413ZG Devices */
|
||||
/* #define STM32F423xx */ /*!< STM32F423CH, STM32F423RH, STM32F423VH and STM32F423ZH Devices */
|
||||
#endif
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
*/
|
||||
#if !defined (USE_HAL_DRIVER)
|
||||
/**
|
||||
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||
In this case, these drivers will not be included and the application code will
|
||||
be based on direct access to peripherals registers
|
||||
*/
|
||||
/*#define USE_HAL_DRIVER */
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS version number V2.6.8
|
||||
*/
|
||||
#define __STM32F4xx_CMSIS_VERSION_MAIN (0x02U) /*!< [31:24] main version */
|
||||
#define __STM32F4xx_CMSIS_VERSION_SUB1 (0x06U) /*!< [23:16] sub1 version */
|
||||
#define __STM32F4xx_CMSIS_VERSION_SUB2 (0x08U) /*!< [15:8] sub2 version */
|
||||
#define __STM32F4xx_CMSIS_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __STM32F4xx_CMSIS_VERSION ((__STM32F4xx_CMSIS_VERSION_MAIN << 24)\
|
||||
|(__STM32F4xx_CMSIS_VERSION_SUB1 << 16)\
|
||||
|(__STM32F4xx_CMSIS_VERSION_SUB2 << 8 )\
|
||||
|(__STM32F4xx_CMSIS_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Device_Included
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F405xx)
|
||||
#include "stm32f405xx.h"
|
||||
#elif defined(STM32F415xx)
|
||||
#include "stm32f415xx.h"
|
||||
#elif defined(STM32F407xx)
|
||||
#include "stm32f407xx.h"
|
||||
#elif defined(STM32F417xx)
|
||||
#include "stm32f417xx.h"
|
||||
#elif defined(STM32F427xx)
|
||||
#include "stm32f427xx.h"
|
||||
#elif defined(STM32F437xx)
|
||||
#include "stm32f437xx.h"
|
||||
#elif defined(STM32F429xx)
|
||||
#include "stm32f429xx.h"
|
||||
#elif defined(STM32F439xx)
|
||||
#include "stm32f439xx.h"
|
||||
#elif defined(STM32F401xC)
|
||||
#include "stm32f401xc.h"
|
||||
#elif defined(STM32F401xE)
|
||||
#include "stm32f401xe.h"
|
||||
#elif defined(STM32F410Tx)
|
||||
#include "stm32f410tx.h"
|
||||
#elif defined(STM32F410Cx)
|
||||
#include "stm32f410cx.h"
|
||||
#elif defined(STM32F410Rx)
|
||||
#include "stm32f410rx.h"
|
||||
#elif defined(STM32F411xE)
|
||||
#include "stm32f411xe.h"
|
||||
#elif defined(STM32F446xx)
|
||||
#include "stm32f446xx.h"
|
||||
#elif defined(STM32F469xx)
|
||||
#include "stm32f469xx.h"
|
||||
#elif defined(STM32F479xx)
|
||||
#include "stm32f479xx.h"
|
||||
#elif defined(STM32F412Cx)
|
||||
#include "stm32f412cx.h"
|
||||
#elif defined(STM32F412Zx)
|
||||
#include "stm32f412zx.h"
|
||||
#elif defined(STM32F412Rx)
|
||||
#include "stm32f412rx.h"
|
||||
#elif defined(STM32F412Vx)
|
||||
#include "stm32f412vx.h"
|
||||
#elif defined(STM32F413xx)
|
||||
#include "stm32f413xx.h"
|
||||
#elif defined(STM32F423xx)
|
||||
#include "stm32f423xx.h"
|
||||
#else
|
||||
#error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Exported_types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESET = 0U,
|
||||
SET = !RESET
|
||||
} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISABLE = 0U,
|
||||
ENABLE = !DISABLE
|
||||
} FunctionalState;
|
||||
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SUCCESS = 0U,
|
||||
ERROR = !SUCCESS
|
||||
} ErrorStatus;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup Exported_macro
|
||||
* @{
|
||||
*/
|
||||
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
#define READ_REG(REG) ((REG))
|
||||
|
||||
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
/* Use of CMSIS compiler intrinsics for register exclusive access */
|
||||
/* Atomic 32-bit register access macro to set one or several bits */
|
||||
#define ATOMIC_SET_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 32-bit register access macro to clear one or several bits */
|
||||
#define ATOMIC_CLEAR_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 32-bit register access macro to clear and set one or several bits */
|
||||
#define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to set one or several bits */
|
||||
#define ATOMIC_SETH_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = __LDREXH((__IO uint16_t *)&(REG)) | (BIT); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to clear one or several bits */
|
||||
#define ATOMIC_CLEARH_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = __LDREXH((__IO uint16_t *)&(REG)) & ~(BIT); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to clear and set one or several bits */
|
||||
#define ATOMIC_MODIFYH_REG(REG, CLEARMSK, SETMASK) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = (__LDREXH((__IO uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined (USE_HAL_DRIVER)
|
||||
#include "stm32f4xx_hal.h"
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __STM32F4xx_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f4xx.h
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f4xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef __SYSTEM_STM32F4XX_H
|
||||
#define __SYSTEM_STM32F4XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */
|
||||
extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SYSTEM_STM32F4XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -0,0 +1,6 @@
|
|||
This software component is provided to you as part of a software package and
|
||||
applicable license terms are in the Package_license file. If you received this
|
||||
software component outside of a package or without applicable license terms,
|
||||
the terms of the Apache-2.0 license shall apply.
|
||||
You may obtain a copy of the Apache-2.0 at:
|
||||
https://opensource.org/licenses/Apache-2.0
|
|
@ -0,0 +1,865 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_ARMCC_H
|
||||
#define __CMSIS_ARMCC_H
|
||||
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
|
||||
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#endif
|
||||
|
||||
/* __ARM_ARCH_8M_BASE__ not applicable */
|
||||
/* __ARM_ARCH_8M_MAIN__ not applicable */
|
||||
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE static __forceinline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __enable_irq(); */
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/**
|
||||
\brief Get Control Register
|
||||
\details Returns the content of the Control Register.
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Control Register
|
||||
\details Writes the given value to the Control Register.
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get IPSR Register
|
||||
\details Returns the content of the IPSR Register.
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get APSR Register
|
||||
\details Returns the content of the APSR Register.
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get xPSR Register
|
||||
\details Returns the content of the xPSR Register.
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Process Stack Pointer
|
||||
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Process Stack Pointer
|
||||
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Main Stack Pointer
|
||||
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Main Stack Pointer
|
||||
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Priority Mask
|
||||
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Priority Mask
|
||||
\details Assigns the given value to the Priority Mask Register.
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief Enable FIQ
|
||||
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable FIQ
|
||||
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Base Priority
|
||||
\details Returns the current value of the Base Priority register.
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority
|
||||
\details Assigns the given value to the Base Priority register.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority with condition
|
||||
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||
or the new value increases the BASEPRI priority level.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||
__regBasePriMax = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Fault Mask
|
||||
\details Returns the current value of the Fault Mask register.
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Fault Mask
|
||||
\details Assigns the given value to the Fault Mask register.
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1U);
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief No Operation
|
||||
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\details Causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
#define __RBIT __rbit
|
||||
#else
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\details Counts the number of leading zeros of a data value.
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right with Extend (32 bit)
|
||||
\details Moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
rrx r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U))
|
||||
{
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U)
|
||||
{
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32U) ) >> 32U))
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
|
@ -0,0 +1,266 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Arm Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Arm Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include <cmsis_iccarm.h>
|
||||
|
||||
|
||||
/*
|
||||
* TI Arm Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __packed__
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM _asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
// NO RETURN is automatically detected hence no warning here
|
||||
#define __NO_RETURN
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||
#define __USED
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED @packed
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT @packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION @packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
|
@ -0,0 +1,935 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
|
||||
* @version V5.0.7
|
||||
* @date 19. June 2018
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2018 IAR Systems
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __CMSIS_ICCARM_H__
|
||||
#define __CMSIS_ICCARM_H__
|
||||
|
||||
#ifndef __ICCARM__
|
||||
#error This file should only be compiled by ICCARM
|
||||
#endif
|
||||
|
||||
#pragma system_include
|
||||
|
||||
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||
*/
|
||||
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
|
||||
/* Macros already defined */
|
||||
#else
|
||||
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
|
||||
#if __ARM_ARCH == 6
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif __ARM_ARCH == 7
|
||||
#if __ARM_FEATURE_DSP
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#else
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
#endif /* __ARM_ARCH */
|
||||
#endif /* __ARM_ARCH_PROFILE == 'M' */
|
||||
#endif
|
||||
|
||||
/* Alternativ core deduction for older ICCARM's */
|
||||
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
|
||||
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
|
||||
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#else
|
||||
#error "Unknown target."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#else
|
||||
#define __IAR_M0_FAMILY 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#if __ICCARM_V8
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE _Pragma("inline=forced")
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint16_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
|
||||
{
|
||||
*(__packed uint16_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint32_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
|
||||
{
|
||||
*(__packed uint32_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__packed struct __iar_u32 { uint32_t v; };
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||
#endif
|
||||
|
||||
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||
|
||||
#if defined(__CLZ)
|
||||
#undef __CLZ
|
||||
#endif
|
||||
#if defined(__REVSH)
|
||||
#undef __REVSH
|
||||
#endif
|
||||
#if defined(__RBIT)
|
||||
#undef __RBIT
|
||||
#endif
|
||||
#if defined(__SSAT)
|
||||
#undef __SSAT
|
||||
#endif
|
||||
#if defined(__USAT)
|
||||
#undef __USAT
|
||||
#endif
|
||||
|
||||
#include "iccarm_builtin.h"
|
||||
|
||||
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||
#define __disable_irq __iar_builtin_disable_interrupt
|
||||
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||
#define __enable_irq __iar_builtin_enable_interrupt
|
||||
#define __arm_rsr __iar_builtin_rsr
|
||||
#define __arm_wsr __iar_builtin_wsr
|
||||
|
||||
|
||||
#define __get_APSR() (__arm_rsr("APSR"))
|
||||
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
|
||||
#define __get_CONTROL() (__arm_rsr("CONTROL"))
|
||||
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
|
||||
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
|
||||
#else
|
||||
#define __get_FPSCR() ( 0 )
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#define __get_IPSR() (__arm_rsr("IPSR"))
|
||||
#define __get_MSP() (__arm_rsr("MSP"))
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
#define __get_MSPLIM() (0U)
|
||||
#else
|
||||
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
|
||||
#endif
|
||||
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
|
||||
#define __get_PSP() (__arm_rsr("PSP"))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __get_PSPLIM() (0U)
|
||||
#else
|
||||
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
|
||||
#endif
|
||||
|
||||
#define __get_xPSR() (__arm_rsr("xPSR"))
|
||||
|
||||
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
|
||||
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
|
||||
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
|
||||
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
|
||||
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
#define __set_MSPLIM(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
|
||||
#endif
|
||||
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
|
||||
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __set_PSPLIM(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
|
||||
#endif
|
||||
|
||||
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
|
||||
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
|
||||
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
|
||||
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
|
||||
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
|
||||
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
|
||||
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
|
||||
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
|
||||
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
|
||||
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
|
||||
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
|
||||
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
|
||||
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
|
||||
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __TZ_get_PSPLIM_NS() (0U)
|
||||
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
|
||||
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
|
||||
#endif
|
||||
|
||||
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
|
||||
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
|
||||
|
||||
#define __NOP __iar_builtin_no_operation
|
||||
|
||||
#define __CLZ __iar_builtin_CLZ
|
||||
#define __CLREX __iar_builtin_CLREX
|
||||
|
||||
#define __DMB __iar_builtin_DMB
|
||||
#define __DSB __iar_builtin_DSB
|
||||
#define __ISB __iar_builtin_ISB
|
||||
|
||||
#define __LDREXB __iar_builtin_LDREXB
|
||||
#define __LDREXH __iar_builtin_LDREXH
|
||||
#define __LDREXW __iar_builtin_LDREX
|
||||
|
||||
#define __RBIT __iar_builtin_RBIT
|
||||
#define __REV __iar_builtin_REV
|
||||
#define __REV16 __iar_builtin_REV16
|
||||
|
||||
__IAR_FT int16_t __REVSH(int16_t val)
|
||||
{
|
||||
return (int16_t) __iar_builtin_REVSH(val);
|
||||
}
|
||||
|
||||
#define __ROR __iar_builtin_ROR
|
||||
#define __RRX __iar_builtin_RRX
|
||||
|
||||
#define __SEV __iar_builtin_SEV
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __SSAT __iar_builtin_SSAT
|
||||
#endif
|
||||
|
||||
#define __STREXB __iar_builtin_STREXB
|
||||
#define __STREXH __iar_builtin_STREXH
|
||||
#define __STREXW __iar_builtin_STREX
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __USAT __iar_builtin_USAT
|
||||
#endif
|
||||
|
||||
#define __WFE __iar_builtin_WFE
|
||||
#define __WFI __iar_builtin_WFI
|
||||
|
||||
#if __ARM_MEDIA__
|
||||
#define __SADD8 __iar_builtin_SADD8
|
||||
#define __QADD8 __iar_builtin_QADD8
|
||||
#define __SHADD8 __iar_builtin_SHADD8
|
||||
#define __UADD8 __iar_builtin_UADD8
|
||||
#define __UQADD8 __iar_builtin_UQADD8
|
||||
#define __UHADD8 __iar_builtin_UHADD8
|
||||
#define __SSUB8 __iar_builtin_SSUB8
|
||||
#define __QSUB8 __iar_builtin_QSUB8
|
||||
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||
#define __USUB8 __iar_builtin_USUB8
|
||||
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||
#define __SADD16 __iar_builtin_SADD16
|
||||
#define __QADD16 __iar_builtin_QADD16
|
||||
#define __SHADD16 __iar_builtin_SHADD16
|
||||
#define __UADD16 __iar_builtin_UADD16
|
||||
#define __UQADD16 __iar_builtin_UQADD16
|
||||
#define __UHADD16 __iar_builtin_UHADD16
|
||||
#define __SSUB16 __iar_builtin_SSUB16
|
||||
#define __QSUB16 __iar_builtin_QSUB16
|
||||
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||
#define __USUB16 __iar_builtin_USUB16
|
||||
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||
#define __SASX __iar_builtin_SASX
|
||||
#define __QASX __iar_builtin_QASX
|
||||
#define __SHASX __iar_builtin_SHASX
|
||||
#define __UASX __iar_builtin_UASX
|
||||
#define __UQASX __iar_builtin_UQASX
|
||||
#define __UHASX __iar_builtin_UHASX
|
||||
#define __SSAX __iar_builtin_SSAX
|
||||
#define __QSAX __iar_builtin_QSAX
|
||||
#define __SHSAX __iar_builtin_SHSAX
|
||||
#define __USAX __iar_builtin_USAX
|
||||
#define __UQSAX __iar_builtin_UQSAX
|
||||
#define __UHSAX __iar_builtin_UHSAX
|
||||
#define __USAD8 __iar_builtin_USAD8
|
||||
#define __USADA8 __iar_builtin_USADA8
|
||||
#define __SSAT16 __iar_builtin_SSAT16
|
||||
#define __USAT16 __iar_builtin_USAT16
|
||||
#define __UXTB16 __iar_builtin_UXTB16
|
||||
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||
#define __SXTB16 __iar_builtin_SXTB16
|
||||
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||
#define __SMUAD __iar_builtin_SMUAD
|
||||
#define __SMUADX __iar_builtin_SMUADX
|
||||
#define __SMMLA __iar_builtin_SMMLA
|
||||
#define __SMLAD __iar_builtin_SMLAD
|
||||
#define __SMLADX __iar_builtin_SMLADX
|
||||
#define __SMLALD __iar_builtin_SMLALD
|
||||
#define __SMLALDX __iar_builtin_SMLALDX
|
||||
#define __SMUSD __iar_builtin_SMUSD
|
||||
#define __SMUSDX __iar_builtin_SMUSDX
|
||||
#define __SMLSD __iar_builtin_SMLSD
|
||||
#define __SMLSDX __iar_builtin_SMLSDX
|
||||
#define __SMLSLD __iar_builtin_SMLSLD
|
||||
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||
#define __SEL __iar_builtin_SEL
|
||||
#define __QADD __iar_builtin_QADD
|
||||
#define __QSUB __iar_builtin_QSUB
|
||||
#define __PKHBT __iar_builtin_PKHBT
|
||||
#define __PKHTB __iar_builtin_PKHTB
|
||||
#endif
|
||||
|
||||
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#define __CLZ __cmsis_iar_clz_not_active
|
||||
#define __SSAT __cmsis_iar_ssat_not_active
|
||||
#define __USAT __cmsis_iar_usat_not_active
|
||||
#define __RBIT __cmsis_iar_rbit_not_active
|
||||
#define __get_APSR __cmsis_iar_get_APSR_not_active
|
||||
#endif
|
||||
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
|
||||
#endif
|
||||
|
||||
#ifdef __INTRINSICS_INCLUDED
|
||||
#error intrinsics.h is already included previously!
|
||||
#endif
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#undef __CLZ
|
||||
#undef __SSAT
|
||||
#undef __USAT
|
||||
#undef __RBIT
|
||||
#undef __get_APSR
|
||||
|
||||
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
|
||||
{
|
||||
if (data == 0U) { return 32U; }
|
||||
|
||||
uint32_t count = 0U;
|
||||
uint32_t mask = 0x80000000U;
|
||||
|
||||
while ((data & mask) == 0U)
|
||||
{
|
||||
count += 1U;
|
||||
mask = mask >> 1U;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
|
||||
{
|
||||
uint8_t sc = 31U;
|
||||
uint32_t r = v;
|
||||
for (v >>= 1U; v; v >>= 1U)
|
||||
{
|
||||
r <<= 1U;
|
||||
r |= v & 1U;
|
||||
sc--;
|
||||
}
|
||||
return (r << sc);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm("MRS %0,APSR" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#undef __get_FPSCR
|
||||
#undef __set_FPSCR
|
||||
#define __get_FPSCR() (0)
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
#pragma diag_suppress=Pe177
|
||||
|
||||
#define __enable_irq __enable_interrupt
|
||||
#define __disable_irq __disable_interrupt
|
||||
#define __NOP __no_operation
|
||||
|
||||
#define __get_xPSR __get_PSR
|
||||
|
||||
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
|
||||
|
||||
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
|
||||
{
|
||||
return __LDREX((unsigned long *)ptr);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
|
||||
{
|
||||
return __STREX(value, (unsigned long *)ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
__IAR_FT uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
return(result);
|
||||
}
|
||||
|
||||
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
|
||||
}
|
||||
|
||||
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||
}
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
__IAR_FT uint32_t __get_MSPLIM(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_MSPLIM(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __get_PSPLIM(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_PSPLIM(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_SP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,SP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR SP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U))
|
||||
{
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U)
|
||||
{
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
|
||||
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
|
||||
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#undef __IAR_FT
|
||||
#undef __IAR_M0_FAMILY
|
||||
#undef __ICCARM_V8
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
#pragma diag_default=Pe177
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
|
@ -0,0 +1,39 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CMSIS_VERSION_H
|
||||
#define __CMSIS_VERSION_H
|
||||
|
||||
/* CMSIS Version definitions */
|
||||
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
|
||||
#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */
|
||||
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
|
||||
#endif
|
|
@ -0,0 +1,949 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.5
|
||||
* @date 28. May 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M0
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000U
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M0 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* The following EXC_RETURN values are saved the LR on exception entry */
|
||||
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Encode Priority
|
||||
\details Encodes the priority for an interrupt with the given priority group,
|
||||
preemptive priority value, and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [in] SubPriority Subpriority value (starting from 0).
|
||||
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
return (
|
||||
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Decode Priority
|
||||
\details Decodes an interrupt priority value with a given priority group to
|
||||
preemptive priority value and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
|
@ -0,0 +1,976 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm1.h
|
||||
* @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File
|
||||
* @version V1.0.0
|
||||
* @date 23. July 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM1_H_GENERIC
|
||||
#define __CORE_CM1_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M1
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM1 definitions */
|
||||
#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (1U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM1_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM1_H_DEPENDANT
|
||||
#define __CORE_CM1_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM1_REV
|
||||
#define __CM1_REV 0x0100U
|
||||
#warning "__CM1_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M1 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
|
||||
\brief Type definitions for the System Control and ID Register not in the SCB
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control and ID Register not in the SCB.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t RESERVED0[2U];
|
||||
__IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
|
||||
} SCnSCB_Type;
|
||||
|
||||
/* Auxiliary Control Register Definitions */
|
||||
#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */
|
||||
#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */
|
||||
|
||||
#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */
|
||||
#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCnotSCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M1 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* The following EXC_RETURN values are saved the LR on exception entry */
|
||||
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Encode Priority
|
||||
\details Encodes the priority for an interrupt with the given priority group,
|
||||
preemptive priority value, and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [in] SubPriority Subpriority value (starting from 0).
|
||||
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
return (
|
||||
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Decode Priority
|
||||
\details Decodes an interrupt priority value with a given priority group to
|
||||
preemptive priority value and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM1_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
|
@ -0,0 +1,270 @@
|
|||
/******************************************************************************
|
||||
* @file mpu_armv7.h
|
||||
* @brief CMSIS MPU API for Armv7-M MPU
|
||||
* @version V5.0.4
|
||||
* @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 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)))
|
||||
|
||||
/**
|
||||
* 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 non-shareable) or 010b (if 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) & 2U), ((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)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/** 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 orderedCpy(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) {
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
|
||||
table += MPU_TYPE_RALIASES;
|
||||
cnt -= MPU_TYPE_RALIASES;
|
||||
}
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
|
||||
#endif
|