@@ -0,0 +1,63 @@ | |||
/***********************头文件****************************/ | |||
#include "exti.h" | |||
/********************************************** | |||
//外部中断初始化程序 | |||
***********************************************/ | |||
void EXTIX_Init(void) | |||
{ | |||
NVIC_InitTypeDef NVIC_InitStructure; | |||
EXTI_InitTypeDef EXTI_InitStructure; | |||
/***************使能SYSCFG时钟***************/ | |||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟 | |||
/***************初始化IO口******************* | |||
PI4 -> I14 外部中断输入 | |||
PI5 -> I15 外部输入1 | |||
PI6 -> I16 外部输入2 | |||
**********************************************/ | |||
GPIO_InitTypeDef GPIO_InitStructure; | |||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI, ENABLE);//使能GPIOB时钟 | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//PI4 = I14 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 | |||
GPIO_Init(GPIOI, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//输入上拉 | |||
GPIO_Init(GPIOI, &GPIO_InitStructure);//初始化GPIO | |||
/***************设置IO口与中断线的映射关系***************/ | |||
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOI, EXTI_PinSource4);//PI4 连接到中断线4 | |||
/***************初始化线上中断,设置触发条件***************/ | |||
EXTI_InitStructure.EXTI_Line = EXTI_Line4; //选择线上中断 | |||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断事件 | |||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 | |||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能 | |||
EXTI_Init(&EXTI_InitStructure);//配置 | |||
/***************中断使能***************/ | |||
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4 | |||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1 | |||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2 | |||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道 | |||
NVIC_Init(&NVIC_InitStructure);//配置 | |||
} | |||
@@ -0,0 +1,42 @@ | |||
#ifndef __EXTI_H | |||
#define __EXTI_H | |||
/***********************头文件****************************/ | |||
#include "sys.h" | |||
#include "delay.h" | |||
#include "led.h" | |||
#include "includes.h" | |||
/***********************宏函数****************************/ | |||
#define KEY_IN PIin(4) //PI13 外部中断输入引脚 | |||
#define KEY0 PIin(5) //PI15 外部输入1 | |||
#define KEY1 PIin(6) //PI16 外部输入2 | |||
/***********************函数声明****************************/ | |||
void EXTIX_Init(void); //外部中断初始化 | |||
#endif | |||
@@ -0,0 +1,74 @@ | |||
/***********************头文件****************************/ | |||
#include "led.h" | |||
/***********************LED IO初始化****************************/ | |||
void LED_Init(void) | |||
{ | |||
/**************初始化GPIOF、GPIOI******************* | |||
PF6 -> Q0 | |||
PF8 -> Q1 | |||
PF7 -> Q2 | |||
PF9 -> Q3 | |||
PF11 -> Q16 | |||
PI8 -> Q4 | |||
***************************************************/ | |||
GPIO_InitTypeDef GPIO_InitStructure; | |||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟 | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_11 ;//LED0/1/2/3对应IO口 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 | |||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 | |||
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_SetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_8); | |||
GPIO_SetBits(GPIOF,GPIO_Pin_7 | GPIO_Pin_9 |GPIO_Pin_11); | |||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI, ENABLE);//使能GPIOI时钟 | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ;//LED4对应IO口 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 | |||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//下拉 | |||
GPIO_Init(GPIOI, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_SetBits(GPIOI,GPIO_Pin_8); | |||
/**************初始化GPIOE、GPIOG、GPIOH******************* | |||
PE6 -> Q5 | |||
PE5 -> Q6 | |||
PE4 -> Q7 | |||
PG7 -> Q10 | |||
PG6 -> Q11 | |||
PH9 -> Q12 | |||
PH8 -> Q13 | |||
PH7 -> Q14 | |||
PH6 -> Q15 | |||
PH5 -> Q20 | |||
**********************************************************/ | |||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG| RCC_AHB1Periph_GPIOH, ENABLE); | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5 |GPIO_Pin_4 ;//LED5 LED6 LED7对应IO口 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 | |||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//开漏输出 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 | |||
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 |GPIO_Pin_4); | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 ;//LED7 LED8 对应IO口 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 | |||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 | |||
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_SetBits(GPIOG,GPIO_Pin_7 | GPIO_Pin_6); | |||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 |GPIO_Pin_7 |GPIO_Pin_6 |GPIO_Pin_5 ;//LED9 LED10 LED11 LED12 对应IO口 | |||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 | |||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//开漏输出 | |||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz | |||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 | |||
GPIO_Init(GPIOH, &GPIO_InitStructure);//初始化GPIO | |||
GPIO_SetBits(GPIOH,GPIO_Pin_9 | GPIO_Pin_8 |GPIO_Pin_7 |GPIO_Pin_6 |GPIO_Pin_5); | |||
} | |||
@@ -0,0 +1,40 @@ | |||
#ifndef __LED_H | |||
#define __LED_H | |||
#include "sys.h" | |||
////////////////////////////////////////////////////////////////////////////////// | |||
//本程序只供学习使用,未经作者许可,不得用于其它任何用途 | |||
//ALIENTEK STM32F407开发板 | |||
//LED驱动代码 | |||
//正点原子@ALIENTEK | |||
//技术论坛:www.openedv.com | |||
//创建日期:2014/5/2 | |||
//版本:V1.0 | |||
//版权所有,盗版必究。 | |||
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 | |||
//All rights reserved | |||
////////////////////////////////////////////////////////////////////////////////// | |||
//LED端口定义 | |||
#define LED0 PFout(6) // Q0 | |||
#define LED1 PFout(8) // Q1 | |||
#define LED2 PFout(7) // Q2 | |||
#define LED3 PFout(9) // Q3 | |||
#define LED4 PIout(8) // Q4 | |||
#define LED5 PEout(6) // Q5 | |||
#define LED6 PEout(5) // Q6 | |||
#define LED7 PEout(4) // Q7 | |||
#define LED8 PGout(7) // Q10 | |||
#define LED9 PGout(6) // Q11 | |||
#define LED10 PHout(9) // Q12 | |||
#define LED11 PHout(8) // Q13 | |||
#define LED12 PHout(7) // Q14 | |||
#define LED13 PHout(6) // Q15 | |||
#define LED14 PFout(11) // Q16 | |||
#define LED15 PHout(5) // Q20 | |||
void LED_Init(void);//初始化 | |||
#endif |
@@ -0,0 +1,31 @@ | |||
/***********************头文件****************************/ | |||
#include "timer.h" | |||
#include "led.h" | |||
/************************************************** | |||
//通用定时器3中断初始化 | |||
//arr:自动重装值。 | |||
//psc:时钟预分频数 | |||
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us. | |||
//Ft=定时器工作频率,单位:Mhz | |||
//这里使用的是定时器3! | |||
**************************************************/ | |||
void TIM3_Int_Init(u16 arr,u16 psc) | |||
{ | |||
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; | |||
NVIC_InitTypeDef NVIC_InitStructure; | |||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能TIM3时钟 | |||
TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值 | |||
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频 | |||
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 | |||
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; | |||
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3 | |||
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断 | |||
TIM_Cmd(TIM3,ENABLE); //使能定时器3 | |||
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断 | |||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1 | |||
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3 | |||
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; | |||
NVIC_Init(&NVIC_InitStructure); | |||
} | |||
@@ -0,0 +1,10 @@ | |||
#ifndef _TIMER_H | |||
#define _TIMER_H | |||
/***********************头文件****************************/ | |||
#include "sys.h" | |||
/***********************函数声明****************************/ | |||
void TIM3_Int_Init(u16 arr,u16 psc); | |||
#endif |
@@ -0,0 +1,305 @@ | |||
#include "delay.h" | |||
#include "sys.h" | |||
////////////////////////////////////////////////////////////////////////////////// | |||
//如果使用OS,则包括下面的头文件(以ucos为例)即可. | |||
#if SYSTEM_SUPPORT_OS | |||
#include "includes.h" //支持OS时,使用 | |||
#endif | |||
static u8 fac_us=0; //us延时倍乘数 | |||
static u16 fac_ms=0; //ms延时倍乘数,在os下,代表每个节拍的ms数 | |||
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS). | |||
//当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持 | |||
//首先是3个宏定义: | |||
// delay_osrunning:用于表示OS当前是否正在运行,以决定是否可以使用相关函数 | |||
//delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始哈systick | |||
// delay_osintnesting:用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行 | |||
//然后是3个函数: | |||
// delay_osschedlock:用于锁定OS任务调度,禁止调度 | |||
//delay_osschedunlock:用于解锁OS任务调度,重新开启调度 | |||
// delay_ostimedly:用于OS延时,可以引起任务调度. | |||
//本例程仅作UCOSII和UCOSIII的支持,其他OS,请自行参考着移植 | |||
//支持UCOSII | |||
#ifdef OS_CRITICAL_METHOD //OS_CRITICAL_METHOD定义了,说明要支持UCOSII | |||
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行 | |||
#define delay_ostickspersec OS_TICKS_PER_SEC //OS时钟节拍,即每秒调度次数 | |||
#define delay_osintnesting OSIntNesting //中断嵌套级别,即中断嵌套次数 | |||
#endif | |||
//支持UCOSIII | |||
#ifdef CPU_CFG_CRITICAL_METHOD //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII | |||
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行 | |||
#define delay_ostickspersec OSCfg_TickRate_Hz //OS时钟节拍,即每秒调度次数 | |||
#define delay_osintnesting OSIntNestingCtr //中断嵌套级别,即中断嵌套次数 | |||
#endif | |||
//us级延时时,关闭任务调度(防止打断us级延迟) | |||
void delay_osschedlock(void) | |||
{ | |||
#ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII | |||
OS_ERR err; | |||
OSSchedLock(&err); //UCOSIII的方式,禁止调度,防止打断us延时 | |||
#else //否则UCOSII | |||
OSSchedLock(); //UCOSII的方式,禁止调度,防止打断us延时 | |||
#endif | |||
} | |||
//us级延时时,恢复任务调度 | |||
void delay_osschedunlock(void) | |||
{ | |||
#ifdef CPU_CFG_CRITICAL_METHOD //使用UCOSIII | |||
OS_ERR err; | |||
OSSchedUnlock(&err); //UCOSIII的方式,恢复调度 | |||
#else //否则UCOSII | |||
OSSchedUnlock(); //UCOSII的方式,恢复调度 | |||
#endif | |||
} | |||
//调用OS自带的延时函数延时 | |||
//ticks:延时的节拍数 | |||
//比如ticks = 5;现在默认一个节拍5ms , 则5个节拍延时25ms | |||
void delay_ostimedly(u32 ticks) | |||
{ | |||
#ifdef CPU_CFG_CRITICAL_METHOD | |||
OS_ERR err; | |||
OSTimeDly(ticks,OS_OPT_TIME_PERIODIC,&err);//UCOSIII延时采用周期模式 | |||
#else | |||
OSTimeDly(ticks); //UCOSII延时 | |||
#endif | |||
} | |||
//systick中断服务函数,使用OS时用到 | |||
void SysTick_Handler(void) | |||
{ | |||
if(delay_osrunning==1) //OS开始跑了,才执行正常的调度处理 | |||
{ | |||
OSIntEnter(); //进入中断 | |||
OSTimeTick(); //调用ucos的时钟服务程序 | |||
OSIntExit(); //触发任务切换软中断 | |||
} | |||
} | |||
#endif | |||
//初始化延迟函数 | |||
//当使用OS的时候,此函数会初始化OS的时钟节拍 | |||
//SYSTICK的时钟固定为AHB时钟的1/8 | |||
//SYSCLK:系统时钟频率 | |||
void delay_init(u8 SYSCLK) | |||
{ | |||
#if SYSTEM_SUPPORT_OS //如果需要支持OS. | |||
u32 reload; | |||
#endif | |||
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); | |||
fac_us=SYSCLK/8; //不论是否使用OS,fac_us都需要使用 | |||
#if SYSTEM_SUPPORT_OS //如果需要支持OS. | |||
reload=SYSCLK/8; //每秒钟的计数次数 单位为M | |||
reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间 | |||
//reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右 | |||
fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位 | |||
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断 | |||
SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 | |||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK | |||
#else | |||
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 | |||
#endif | |||
} | |||
#if SYSTEM_SUPPORT_OS //如果需要支持OS. | |||
//延时nus | |||
//nus:要延时的us数. | |||
//nus:0~204522252(最大值即2^32/fac_us@fac_us=21) | |||
void delay_us(u32 nus) | |||
{ | |||
u32 ticks; | |||
u32 told,tnow,tcnt=0; | |||
u32 reload=SysTick->LOAD; //LOAD的值 | |||
ticks=nus*fac_us; //需要的节拍数 | |||
delay_osschedlock(); //阻止OS调度,防止打断us延时 | |||
told=SysTick->VAL; //刚进入时的计数器值 | |||
while(1) | |||
{ | |||
tnow=SysTick->VAL; | |||
if(tnow!=told) | |||
{ | |||
if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了. | |||
else tcnt+=reload-tnow+told; | |||
told=tnow; | |||
if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出. | |||
} | |||
}; | |||
delay_osschedunlock(); //恢复OS调度 | |||
} | |||
//延时nms | |||
//nms:要延时的ms数 | |||
//nms:0~65535 | |||
void delay_ms(u16 nms) | |||
{ | |||
if(delay_osrunning&&delay_osintnesting==0)//如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度) | |||
{ | |||
if(nms>=fac_ms) //延时的时间大于OS的最少时间周期 | |||
{ | |||
delay_ostimedly(nms/fac_ms); //OS延时 | |||
} | |||
nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时 | |||
} | |||
delay_us((u32)(nms*1000)); //普通方式延时 | |||
} | |||
#else //不用ucos时 | |||
//延时nus | |||
//nus为要延时的us数. | |||
//注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21) | |||
void delay_us(u32 nus) | |||
{ | |||
u32 temp; | |||
SysTick->LOAD=nus*fac_us; //时间加载 | |||
SysTick->VAL=0x00; //清空计数器 | |||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 | |||
do | |||
{ | |||
temp=SysTick->CTRL; | |||
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 | |||
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 | |||
SysTick->VAL =0X00; //清空计数器 | |||
} | |||
//延时nms | |||
//注意nms的范围 | |||
//SysTick->LOAD为24位寄存器,所以,最大延时为: | |||
//nms<=0xffffff*8*1000/SYSCLK | |||
//SYSCLK单位为Hz,nms单位为ms | |||
//对168M条件下,nms<=798ms | |||
void delay_xms(u16 nms) | |||
{ | |||
u32 temp; | |||
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit) | |||
SysTick->VAL =0x00; //清空计数器 | |||
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数 | |||
do | |||
{ | |||
temp=SysTick->CTRL; | |||
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 | |||
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 | |||
SysTick->VAL =0X00; //清空计数器 | |||
} | |||
//延时nms | |||
//nms:0~65535 | |||
void delay_ms(u16 nms) | |||
{ | |||
u8 repeat=nms/540; //这里用540,是考虑到某些客户可能超频使用, | |||
//比如超频到248M的时候,delay_xms最大只能延时541ms左右了 | |||
u16 remain=nms%540; | |||
while(repeat) | |||
{ | |||
delay_xms(540); | |||
repeat--; | |||
} | |||
if(remain)delay_xms(remain); | |||
} | |||
#endif | |||
//使用内部时钟函数 | |||
void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) | |||
{ | |||
__IO uint32_t HSIStartUpStatus = 0; | |||
//把RCC外设初始化成复位状态 | |||
RCC_DeInit(); | |||
//使能HSI,HSI = 16M | |||
RCC_HSICmd(ENABLE); | |||
//等待HSI就绪 | |||
HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY; | |||
//只有HSI就绪之后则继续往下执行 | |||
if (HSIStartUpStatus == RCC_CR_HSIRDY) | |||
{ | |||
//调压器电压输出级别配置为1,以便在器件为最大频率工作时 | |||
//性能和功耗实现平衡 | |||
RCC->APB1ENR |= RCC_APB1ENR_PWREN; | |||
PWR->CR |= PWR_CR_VOS; | |||
/* HCLK = SYSCLK / 1*/ | |||
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; | |||
/* PCLK2 = HCLK / 2*/ | |||
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; | |||
/* PCLK1 = HCLK / 4*/ | |||
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; | |||
//如果要超频就带在这里设置 | |||
//设置PLL来源时钟,设置VC0分频因子m,设置VC0倍频因子n, | |||
//设置系统时钟分频因子p,设置OTG,FS,SDIO,RNG分频因子q | |||
RCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q); | |||
//使能PLL | |||
RCC_PLLCmd(ENABLE); | |||
//等待PLL稳定 | |||
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) | |||
{ | |||
} | |||
//配置FLASH预取指,指令缓存,数据缓存和等待状态 | |||
FLASH->ACR = FLASH_ACR_PRFTEN | |||
| FLASH_ACR_ICEN | |||
|FLASH_ACR_DCEN | |||
|FLASH_ACR_LATENCY_5WS; | |||
// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK | |||
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); | |||
//读取时钟切换状态位,确保PLLCLK被选为系统时钟 | |||
while (RCC_GetSYSCLKSource() != 0x08) | |||
{} | |||
} | |||
else | |||
{ | |||
//HSI启动出错处理 | |||
while(1) | |||
{ | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,55 @@ | |||
#ifndef __DELAY_H | |||
#define __DELAY_H | |||
#include <sys.h> | |||
////////////////////////////////////////////////////////////////////////////////// | |||
//本程序只供学习使用,未经作者许可,不得用于其它任何用途 | |||
//ALIENTEK STM32F407开发板 | |||
//使用SysTick的普通计数模式对延迟进行管理(支持ucosii) | |||
//包括delay_us,delay_ms | |||
//正点原子@ALIENTEK | |||
//技术论坛:www.openedv.com | |||
//修改日期:2014/5/2 | |||
//版本:V1.0 | |||
//版权所有,盗版必究。 | |||
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 | |||
//All rights reserved | |||
//******************************************************************************** | |||
//修改说明 | |||
//无 | |||
////////////////////////////////////////////////////////////////////////////////// | |||
void delay_init(u8 SYSCLK); | |||
void delay_ms(u16 nms); | |||
void delay_us(u32 nus); | |||
//使用内部时钟函数 | |||
void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q); | |||
#endif | |||
@@ -0,0 +1,388 @@ | |||
/***********************头文件****************************/ | |||
#include "main.h" | |||
#include "sys.h" | |||
#include "delay.h" | |||
#include "led.h" | |||
#include "exti.h" | |||
#include "includes.h" | |||
#include "timer.h" | |||
/***********************指针变量****************************/ | |||
OS_EVENT * sem_TaskC; //任务C信号量指针 | |||
OS_EVENT * sem_Mutex; //互斥信号量 | |||
OS_EVENT * q_Msg; //消息队列 | |||
void * MsgGrp[256]; //消息队列存储地址,最大支持256个消息 | |||
/***********************全局变量****************************/ | |||
u16 *I3_Num; | |||
static u16 I3_InNum; // 存储邮箱消息 | |||
u32 PB4_Num; //存储按键次数 | |||
u8 flag_Exit; //执行按键函数中断标志位 | |||
uint8_t taskA_Num = 0 ;//记录任务A小灯闪烁次数 | |||
/**********************START 任务****************************/ | |||
#define START_TASK_PRIO 3 //开始任务的优先级 | |||
#define START_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK START_TASK_STK[START_STK_SIZE];//任务任务堆栈 | |||
void start_task(void *pdata);//任务函数 | |||
/**********************任务A*********************************/ | |||
#define LEDA_TASK_PRIO 4 //设置任务优先级 | |||
#define LEDA_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDA_TASK_STK[LEDA_STK_SIZE]; //任务堆栈 | |||
void ledA_task(void *pdata); //任务函数 | |||
/**********************任务B********************************/ | |||
#define LEDB_TASK_PRIO 5 //设置任务优先级 | |||
#define LEDB_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDB_TASK_STK[LEDB_STK_SIZE]; //任务堆栈 | |||
void ledB_task(void *pdata); //任务函数 | |||
/**********************任务C********************************/ | |||
#define LEDC_TASK_PRIO 6 //设置任务优先级 | |||
#define LEDC_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDC_TASK_STK[LEDC_STK_SIZE]; //任务堆栈 | |||
void ledC_task(void *pdata); //任务函数 | |||
/**********************任务D********************************/ | |||
#define LEDD_TASK_PRIO 9 //设置任务优先级 | |||
#define LEDD_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDD_TASK_STK[LEDD_STK_SIZE]; //任务堆栈 | |||
void ledD_task(void *pdata); //任务函数 | |||
/*********************任务E********************************/ | |||
#define LEDE_TASK_PRIO 10 //设置任务优先级 | |||
#define LEDE_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDE_TASK_STK[LEDE_STK_SIZE]; //任务堆栈 | |||
void ledE_task(void *pdata); //任务函数 | |||
/*********************任务F ********************************/ | |||
#define LEDF_TASK_PRIO 7 //设置任务优先级 | |||
#define LEDF_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK LEDF_TASK_STK[LEDF_STK_SIZE]; //任务堆栈 | |||
void ledF_task(void *pdata); //任务函数 | |||
/********************按键检测任务****************************/ | |||
#define KEYG_TASK_PRIO 11 //设置任务优先级 | |||
#define KEYG_STK_SIZE 128 //设置任务堆栈大小 | |||
OS_STK KEYG_TASK_STK[KEYG_STK_SIZE]; //任务堆栈 | |||
void keyG_task(void *pdata); //任务函数 | |||
/********************主函数****************************/ | |||
int main(void) | |||
{ | |||
HSI_SetSysClock(16, 336, 2, 7); //使用HSI配置系统时钟为168M | |||
TIM3_Int_Init(4999, 8399); //时钟初始化 | |||
delay_init(168); //延时初始化 | |||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置 | |||
LED_Init(); //LED初始化 | |||
EXTIX_Init(); //外部中断初始化 | |||
OSInit(); //UCOS初始化 | |||
OSTaskCreate(start_task, (void*)0, (OS_STK*)&START_TASK_STK[START_STK_SIZE-1], START_TASK_PRIO); //创建开始任务 | |||
OSStart(); //开始任务 | |||
} | |||
/****************************************************** | |||
//创建UCOS开始任务 | |||
//提供外设初始化、创建信号量、创建邮箱、创建消息队列 | |||
、创建信号量集、创建任务、初始化统计任务等等 | |||
********************************************************/ | |||
void start_task(void *pdata) | |||
{ | |||
OS_CPU_SR cpu_sr = 0; | |||
pdata=pdata; | |||
u8 err; //错误标志码 | |||
sem_TaskC = OSSemCreate(0); //创建信号量 | |||
msg_TaskC = OSMboxCreate((void*) 0);//创建消息邮箱 | |||
sem_Mutex = OSMutexCreate(8, &err); //创建互斥信号量 设置优先级为8 | |||
q_Msg = OSQCreate(&MsgGrp[0],256); //创建消息队列 | |||
OSStatInit(); //开启统计任务 | |||
OS_ENTER_CRITICAL(); //进入临界区(关闭中断) | |||
OSTaskCreate(ledA_task,(void*)0,(OS_STK*)&LEDA_TASK_STK[LEDA_STK_SIZE-1],LEDA_TASK_PRIO);//创建任务A | |||
OSTaskCreate(ledB_task,(void*)0,(OS_STK*)&LEDB_TASK_STK[LEDB_STK_SIZE-1],LEDB_TASK_PRIO);//创建任务B | |||
OSTaskCreate(ledC_task,(void*)0,(OS_STK*)&LEDC_TASK_STK[LEDC_STK_SIZE-1],LEDC_TASK_PRIO);//创建任务C | |||
OSTaskCreate(ledD_task,(void*)0,(OS_STK*)&LEDD_TASK_STK[LEDD_STK_SIZE-1],LEDD_TASK_PRIO);//创建任务D | |||
OSTaskCreate(ledE_task,(void*)0,(OS_STK*)&LEDE_TASK_STK[LEDE_STK_SIZE-1],LEDE_TASK_PRIO);//创建任务E | |||
OSTaskCreate(ledF_task,(void*)0,(OS_STK*)&LEDF_TASK_STK[LEDF_STK_SIZE-1],LEDF_TASK_PRIO);//创建任务F | |||
OSTaskCreate(keyG_task,(void*)0,(OS_STK*)&KEYG_TASK_STK[KEYG_STK_SIZE-1],KEYG_TASK_PRIO);//创建任务G | |||
OSTaskSuspend(START_TASK_PRIO);//挂起开始任务 | |||
OS_EXIT_CRITICAL(); //退出临界区(开中断) | |||
} | |||
/********************任务A任务函数**************************** | |||
1. 任务A小灯以1Hz的频率闪烁 | |||
2. 当任务A的小灯闪烁10次过后,任务A挂起,任务B执行 | |||
*************************************************************/ | |||
void ledA_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
NVIC_InitTypeDef NVIC_InitStructure; | |||
while(1) | |||
{ | |||
if(21 <= taskA_Num) | |||
{ | |||
LED0 = 1; | |||
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断 | |||
NVIC_InitStructure.NVIC_IRQChannelCmd=DISABLE; | |||
NVIC_Init(&NVIC_InitStructure); | |||
OSTaskSuspend(LEDA_TASK_PRIO);//当小灯闪烁10次后,挂起任务A | |||
} | |||
} | |||
} | |||
/********************任务B任务函数**************************** | |||
1. 任务B小灯以10Hz的频率闪烁 | |||
2. 当任务B的小灯闪烁20次过后,任务B挂起,给任务C发信号量 | |||
*************************************************************/ | |||
void ledB_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
u8 taskB_Num = 0 ;//记录任务A小灯闪烁次数 | |||
while(1) | |||
{ | |||
LED1 = 0; | |||
delay_ms(50); | |||
LED1 = 1; | |||
delay_ms(50); | |||
taskB_Num++; | |||
if(20 <= taskB_Num) | |||
{ | |||
OSSemPost(sem_TaskC);//给任务C发信号量 | |||
OSTaskSuspend(LEDB_TASK_PRIO);//当小灯闪烁20次后,挂起任务B | |||
} | |||
} | |||
} | |||
/********************任务C任务函数**************************** | |||
1. 任务C接收到任务B的信号量时,任务C执行 | |||
2. 对于外部中断的触发次数进行计数,并通过邮箱发送给任务C | |||
3. 中断次数小于5时,任务C小灯以1Hz频率闪烁, | |||
中断次数大于等于5,且小于10时,任务C小灯以10Hz频率闪烁 | |||
4. 任务C把通过邮箱接收到的数据填入队列 | |||
*************************************************************/ | |||
void ledC_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
u8 err; | |||
while (1) | |||
{ | |||
OSSemPend(sem_TaskC, 0, &err); //请求信号量 | |||
I3_Num = (u16* )OSMboxPend(msg_TaskC, 10, &err); //请求邮箱 | |||
if (I3_Num != NULL) //如果消息邮箱没有消息,返回空指针。 | |||
{ | |||
I3_InNum = *I3_Num; | |||
OSQPost(q_Msg, I3_Num); //发送队列消息 | |||
} | |||
if (I3_InNum < 5) | |||
{ | |||
LED2 = 0; | |||
delay_ms(500); | |||
LED2 = 1; | |||
delay_ms(500); | |||
} | |||
else if (I3_InNum >= 5 && I3_InNum < 10) | |||
{ | |||
LED2 = 0; | |||
delay_ms(50); | |||
LED2 = 1; | |||
delay_ms(50); | |||
} | |||
OSSemPost(sem_TaskC); | |||
} | |||
} | |||
/********************任务D任务函数**************************** | |||
1、任务D获取到互斥量时任务D小灯常亮,未获取到时任务D小灯长灭 | |||
2、当外部输入1为高电平时,任务D尝试获取互斥量, | |||
当外部输入1为低电平时,任务D释放互斥量 | |||
*************************************************************/ | |||
void ledD_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
u8 err; | |||
while(1) | |||
{ | |||
if (KEY0 == 0) //外部输入1(PI_15)为高电平,尝试获取互斥信号量 | |||
{ | |||
OSMutexPend(sem_Mutex, 10, &err); | |||
if (err != 10u) | |||
{ | |||
LED3 = 0; | |||
} | |||
} | |||
if (KEY0 == 1) //外部输入1为低电平,释放互斥信号量 | |||
{ | |||
OSMutexPost(sem_Mutex); | |||
LED3 = 1; | |||
} | |||
delay_ms(10); //任务调度 | |||
} | |||
} | |||
/********************任务E任务函数**************************** | |||
1、任务E获取到互斥量时任务E小灯常亮,未获取到时任务E小灯长灭 | |||
2、当外部输入2为高电平时,任务E尝试获取互斥量, | |||
当外部输入2为低电平时,任务E释放互斥量 | |||
*************************************************************/ | |||
void ledE_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
u8 err; | |||
while(1) | |||
{ | |||
if (KEY1 == 0) //外部输入2为高电平,尝试获取互斥信号量 | |||
{ | |||
OSMutexPend(sem_Mutex, 10, &err); | |||
if (err != 10u) | |||
{ | |||
LED4 = 0; | |||
} | |||
} | |||
if (KEY1 == 1) //外部输入2为低电平,释放互斥信号量 | |||
{ | |||
OSMutexPost(sem_Mutex); | |||
LED4 = 1; | |||
} | |||
delay_ms(10); | |||
} | |||
} | |||
/********************任务F任务函数**************************** | |||
1、任务E获取到互斥量时任务E小灯常亮,未获取到时任务E小灯长灭 | |||
2、当外部输入2为高电平时,任务E尝试获取互斥量, | |||
当外部输入2为低电平时,任务E释放互斥量 | |||
*************************************************************/ | |||
void ledF_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
u8 err; | |||
u8 num; | |||
u8 *p; | |||
while(1) | |||
{ | |||
p = OSQPend(q_Msg, 0, &err); //请求消息队列 | |||
if (p != NULL) | |||
{ | |||
num = *p % 8; | |||
} | |||
switch (num) | |||
{ | |||
case 0: | |||
LED5 = 1; LED6 = 1; LED7 = 1; LED8 = 1; LED9 = 1; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 1: | |||
LED5 = 0; LED6 = 1; LED7 = 1; LED8 = 1; LED9 = 1; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 2: | |||
LED5 = 0; LED6 = 0; LED7 = 1; LED8 = 1; LED9 = 1; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 3: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 1; LED9 = 1; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 4: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 1; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 5: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 1; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 6: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 1; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 7: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 1; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 8: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 0; LED13 = 1; LED14 = 1; LED15 = 1; | |||
break; | |||
case 9: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 0; LED13 = 0; LED14 = 1; LED15 = 1; | |||
break; | |||
case 10: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 0; LED13 = 0; LED14 = 0; LED15 = 1; | |||
break; | |||
case 11: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 0; LED13 = 0; LED14 = 0; LED15 = 0; | |||
break; | |||
default: | |||
LED5 = 0; LED6 = 0; LED7 = 0; LED8 = 0; LED9 = 0; LED10 = 0; LED11 = 0; | |||
LED12 = 0; LED13 = 0; LED14 = 0; LED15 = 0; | |||
break; | |||
} | |||
delay_ms(20); //任务调度 | |||
} | |||
} | |||
//按键检测任务 | |||
void keyG_task(void *pdata) | |||
{ | |||
pdata=pdata; | |||
NVIC_InitTypeDef NVIC_InitStructure; | |||
while (1) | |||
{ | |||
if (flag_Exit == 1) | |||
{ | |||
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4 | |||
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;//使能外部中断通道 | |||
NVIC_Init(&NVIC_InitStructure);//配置 | |||
PB4_Num++; | |||
OSMboxPost(msg_TaskC, &PB4_Num); //发送邮箱消息 | |||
delay_ms(500); | |||
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4 | |||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道 | |||
NVIC_Init(&NVIC_InitStructure);//配置 | |||
flag_Exit = 0; | |||
} | |||
} | |||
} | |||
//外部中断4服务程序---由PB4下降沿触发 | |||
//中断服务程序不能调用可能会导致任务调度的函数 | |||
void EXTI4_IRQHandler(void) | |||
{ | |||
OSIntEnter(); //进入中断处理 | |||
flag_Exit = 1; | |||
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位 | |||
OSIntExit(); //退出中断处理 | |||
} | |||
//定时器3中断服务函数 | |||
void TIM3_IRQHandler(void) | |||
{ | |||
OSIntEnter(); //进入中断处理 | |||
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断 | |||
{ | |||
LED0=!LED0;//LED0翻转 | |||
taskA_Num++; | |||
} | |||
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位 | |||
OSIntExit(); //退出中断处理 | |||
} | |||
@@ -0,0 +1,6 @@ | |||
#ifndef __MAIN_H | |||
#define __MAIN_H | |||
#include "includes.h" | |||
OS_EVENT * msg_TaskC; //ÈÎÎñCÏûÏ¢ÓÊÏä | |||
#endif |
@@ -0,0 +1,125 @@ | |||
/** | |||
****************************************************************************** | |||
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_conf.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief Library configuration file. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_CONF_H | |||
#define __STM32F4xx_CONF_H | |||
/* Includes ------------------------------------------------------------------*/ | |||
/* Uncomment the line below to enable peripheral header file inclusion */ | |||
#include "stm32f4xx_adc.h" | |||
#include "stm32f4xx_crc.h" | |||
#include "stm32f4xx_dbgmcu.h" | |||
#include "stm32f4xx_dma.h" | |||
#include "stm32f4xx_exti.h" | |||
#include "stm32f4xx_flash.h" | |||
#include "stm32f4xx_gpio.h" | |||
#include "stm32f4xx_i2c.h" | |||
#include "stm32f4xx_iwdg.h" | |||
#include "stm32f4xx_pwr.h" | |||
#include "stm32f4xx_rcc.h" | |||
#include "stm32f4xx_rtc.h" | |||
#include "stm32f4xx_sdio.h" | |||
#include "stm32f4xx_spi.h" | |||
#include "stm32f4xx_syscfg.h" | |||
#include "stm32f4xx_tim.h" | |||
#include "stm32f4xx_usart.h" | |||
#include "stm32f4xx_wwdg.h" | |||
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ | |||
#if defined (STM32F429_439xx) | |||
#include "stm32f4xx_cryp.h" | |||
#include "stm32f4xx_hash.h" | |||
#include "stm32f4xx_rng.h" | |||
#include "stm32f4xx_can.h" | |||
#include "stm32f4xx_dac.h" | |||
#include "stm32f4xx_dcmi.h" | |||
#include "stm32f4xx_dma2d.h" | |||
#include "stm32f4xx_fmc.h" | |||
#include "stm32f4xx_ltdc.h" | |||
#include "stm32f4xx_sai.h" | |||
#endif /* STM32F429_439xx */ | |||
#if defined (STM32F427_437xx) | |||
#include "stm32f4xx_cryp.h" | |||
#include "stm32f4xx_hash.h" | |||
#include "stm32f4xx_rng.h" | |||
#include "stm32f4xx_can.h" | |||
#include "stm32f4xx_dac.h" | |||
#include "stm32f4xx_dcmi.h" | |||
#include "stm32f4xx_dma2d.h" | |||
#include "stm32f4xx_fmc.h" | |||
#include "stm32f4xx_sai.h" | |||
#endif /* STM32F427_437xx */ | |||
#if defined (STM32F40_41xxx) | |||
#include "stm32f4xx_cryp.h" | |||
#include "stm32f4xx_hash.h" | |||
#include "stm32f4xx_rng.h" | |||
#include "stm32f4xx_can.h" | |||
#include "stm32f4xx_dac.h" | |||
#include "stm32f4xx_dcmi.h" | |||
#include "stm32f4xx_fsmc.h" | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F411xE) | |||
#include "stm32f4xx_flash_ramfunc.h" | |||
#endif /* STM32F411xE */ | |||
/* Exported types ------------------------------------------------------------*/ | |||
/* Exported constants --------------------------------------------------------*/ | |||
/* If an external clock source is used, then the value of the following define | |||
should be set to the value of the external clock source, else, if no external | |||
clock is used, keep this define commented */ | |||
/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */ | |||
/* Uncomment the line below to expanse the "assert_param" macro in the | |||
Standard Peripheral Library drivers code */ | |||
/* #define USE_FULL_ASSERT 1 */ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
#ifdef USE_FULL_ASSERT | |||
/** | |||
* @brief The assert_param macro is used for function's parameters check. | |||
* @param expr: If expr is false, it calls assert_failed function | |||
* which reports the name of the source file and the source | |||
* line number of the call that failed. | |||
* If expr is true, it returns no value. | |||
* @retval None | |||
*/ | |||
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) | |||
/* Exported functions ------------------------------------------------------- */ | |||
void assert_failed(uint8_t* file, uint32_t line); | |||
#else | |||
#define assert_param(expr) ((void)0) | |||
#endif /* USE_FULL_ASSERT */ | |||
#endif /* __STM32F4xx_CONF_H */ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,170 @@ | |||
/** | |||
****************************************************************************** | |||
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_it.c | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief Main Interrupt Service Routines. | |||
* This file provides template for all exceptions handler and | |||
* peripherals interrupt service routine. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx_it.h" | |||
#include "ucos_ii.h" | |||
/** @addtogroup Template_Project | |||
* @{ | |||
*/ | |||
/* Private typedef -----------------------------------------------------------*/ | |||
/* Private define ------------------------------------------------------------*/ | |||
/* Private macro -------------------------------------------------------------*/ | |||
/* Private variables ---------------------------------------------------------*/ | |||
/* Private function prototypes -----------------------------------------------*/ | |||
/* Private functions ---------------------------------------------------------*/ | |||
/******************************************************************************/ | |||
/* Cortex-M4 Processor Exceptions Handlers */ | |||
/******************************************************************************/ | |||
/** | |||
* @brief This function handles NMI exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void NMI_Handler(void) | |||
{ | |||
} | |||
/** | |||
* @brief This function handles Hard Fault exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void HardFault_Handler(void) | |||
{ | |||
/* Go to infinite loop when Hard Fault exception occurs */ | |||
while (1) | |||
{ | |||
} | |||
} | |||
/** | |||
* @brief This function handles Memory Manage exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void MemManage_Handler(void) | |||
{ | |||
/* Go to infinite loop when Memory Manage exception occurs */ | |||
while (1) | |||
{ | |||
} | |||
} | |||
/** | |||
* @brief This function handles Bus Fault exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void BusFault_Handler(void) | |||
{ | |||
/* Go to infinite loop when Bus Fault exception occurs */ | |||
while (1) | |||
{ | |||
} | |||
} | |||
/** | |||
* @brief This function handles Usage Fault exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void UsageFault_Handler(void) | |||
{ | |||
/* Go to infinite loop when Usage Fault exception occurs */ | |||
while (1) | |||
{ | |||
} | |||
} | |||
/** | |||
* @brief This function handles SVCall exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void SVC_Handler(void) | |||
{ | |||
} | |||
/** | |||
* @brief This function handles Debug Monitor exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void DebugMon_Handler(void) | |||
{ | |||
} | |||
/** | |||
* @brief This function handles PendSVC exception. | |||
* @param None | |||
* @retval None | |||
*/ | |||
/*void PendSV_Handler(void) | |||
{ | |||
} | |||
*/ | |||
/** | |||
* @brief This function handles SysTick Handler. | |||
* @param None | |||
* @retval None | |||
*/ | |||
/*void SysTick_Handler(void) | |||
{ | |||
OSIntEnter(); | |||
OSTimeTick(); | |||
OSIntExit(); | |||
} | |||
*/ | |||
/******************************************************************************/ | |||
/* STM32F4xx Peripherals Interrupt Handlers */ | |||
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ | |||
/* available peripheral interrupt handler's name please refer to the startup */ | |||
/* file (startup_stm32f4xx.s). */ | |||
/******************************************************************************/ | |||
/** | |||
* @brief This function handles PPP interrupt request. | |||
* @param None | |||
* @retval None | |||
*/ | |||
/*void PPP_IRQHandler(void) | |||
{ | |||
}*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,60 @@ | |||
/** | |||
****************************************************************************** | |||
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_it.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains the headers of the interrupt handlers. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_IT_H | |||
#define __STM32F4xx_IT_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/* Exported types ------------------------------------------------------------*/ | |||
/* Exported constants --------------------------------------------------------*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions ------------------------------------------------------- */ | |||
void NMI_Handler(void); | |||
void HardFault_Handler(void); | |||
void MemManage_Handler(void); | |||
void BusFault_Handler(void); | |||
void UsageFault_Handler(void); | |||
void SVC_Handler(void); | |||
void DebugMon_Handler(void); | |||
void PendSV_Handler(void); | |||
void SysTick_Handler(void); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* __STM32F4xx_IT_H */ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,49 @@ | |||
#include "sys.h" | |||
//THUMB指令不支持汇编内联 | |||
//采用如下方法实现执行汇编指令WFI | |||
//__asm void WFI_SET(void) | |||
//{ | |||
// WFI; | |||
//} | |||
void WFI_SET(void) | |||
{ | |||
//_ASM volatile("wfi"); | |||
__ASM volatile("wfi"); | |||
} | |||
//关闭所有中断(但是不包括fault和NMI中断) | |||
void INTX_DISABLE(void) | |||
{ | |||
__ASM volatile("cpsid i"); | |||
} | |||
//开启所有中断 | |||
void INTX_ENABLE(void) | |||
{ | |||
__ASM volatile("cpsie i"); | |||
} | |||
//设置栈顶地址 | |||
//addr:栈顶地址 | |||
//__asm void MSR_MSP(u32 addr) | |||
//{ | |||
// MSR MSP, r0 //set Main Stack value | |||
// BX r14 | |||
//} | |||
// | |||
@@ -0,0 +1,83 @@ | |||
#ifndef __SYS_H | |||
#define __SYS_H | |||
#include "stm32f4xx.h" | |||
//0,不支持ucos | |||
//1,支持ucos | |||
#define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持UCOS | |||
//位带操作,实现51类似的GPIO控制功能 | |||
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了. | |||
//IO口操作宏定义 | |||
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) | |||
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) | |||
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) | |||
//IO口地址映射 | |||
#define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014 | |||
#define GPIOB_ODR_Addr (GPIOB_BASE+20) //0x40020414 | |||
#define GPIOC_ODR_Addr (GPIOC_BASE+20) //0x40020814 | |||
#define GPIOD_ODR_Addr (GPIOD_BASE+20) //0x40020C14 | |||
#define GPIOE_ODR_Addr (GPIOE_BASE+20) //0x40021014 | |||
#define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414 | |||
#define GPIOG_ODR_Addr (GPIOG_BASE+20) //0x40021814 | |||
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14 | |||
#define GPIOI_ODR_Addr (GPIOI_BASE+20) //0x40022014 | |||
#define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010 | |||
#define GPIOB_IDR_Addr (GPIOB_BASE+16) //0x40020410 | |||
#define GPIOC_IDR_Addr (GPIOC_BASE+16) //0x40020810 | |||
#define GPIOD_IDR_Addr (GPIOD_BASE+16) //0x40020C10 | |||
#define GPIOE_IDR_Addr (GPIOE_BASE+16) //0x40021010 | |||
#define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410 | |||
#define GPIOG_IDR_Addr (GPIOG_BASE+16) //0x40021810 | |||
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10 | |||
#define GPIOI_IDR_Addr (GPIOI_BASE+16) //0x40022010 | |||
//IO口操作,只对单一的IO口! | |||
//确保n的值小于16! | |||
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 | |||
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 | |||
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 | |||
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 | |||
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出 | |||
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 | |||
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 | |||
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 | |||
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出 | |||
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入 | |||
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 | |||
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入 | |||
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 | |||
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入 | |||
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出 | |||
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入 | |||
#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n) //输出 | |||
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n) //输入 | |||
//以下为汇编函数 | |||
void WFI_SET(void); //执行WFI指令 | |||
void INTX_DISABLE(void);//关闭所有中断 | |||
void INTX_ENABLE(void); //开启所有中断 | |||
void MSR_MSP(u32 addr); //设置堆栈地址 | |||
#endif | |||
@@ -0,0 +1,105 @@ | |||
/** | |||
****************************************************************************** | |||
* @file system_stm32f4xx.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/** @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 | |||
* @{ | |||
*/ | |||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ | |||
/** | |||
* @} | |||
*/ | |||
/** @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 */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,673 @@ | |||
/**************************************************************************//** | |||
* @file core_cm4_simd.h | |||
* @brief CMSIS Cortex-M4 SIMD Header File | |||
* @version V3.20 | |||
* @date 25. February 2013 | |||
* | |||
* @note | |||
* | |||
******************************************************************************/ | |||
/* Copyright (c) 2009 - 2013 ARM LIMITED | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions are met: | |||
- Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | |||
- Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution. | |||
- Neither the name of ARM nor the names of its contributors may be used | |||
to endorse or promote products derived from this software without | |||
specific prior written permission. | |||
* | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE | |||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | |||
---------------------------------------------------------------------------*/ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
#ifndef __CORE_CM4_SIMD_H | |||
#define __CORE_CM4_SIMD_H | |||
/******************************************************************************* | |||
* Hardware Abstraction Layer | |||
******************************************************************************/ | |||
/* ################### Compiler specific Intrinsics ########################### */ | |||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics | |||
Access to dedicated SIMD instructions | |||
@{ | |||
*/ | |||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ | |||
/* ARM armcc specific functions */ | |||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#define __SADD8 __sadd8 | |||
#define __QADD8 __qadd8 | |||
#define __SHADD8 __shadd8 | |||
#define __UADD8 __uadd8 | |||
#define __UQADD8 __uqadd8 | |||
#define __UHADD8 __uhadd8 | |||
#define __SSUB8 __ssub8 | |||
#define __QSUB8 __qsub8 | |||
#define __SHSUB8 __shsub8 | |||
#define __USUB8 __usub8 | |||
#define __UQSUB8 __uqsub8 | |||
#define __UHSUB8 __uhsub8 | |||
#define __SADD16 __sadd16 | |||
#define __QADD16 __qadd16 | |||
#define __SHADD16 __shadd16 | |||
#define __UADD16 __uadd16 | |||
#define __UQADD16 __uqadd16 | |||
#define __UHADD16 __uhadd16 | |||
#define __SSUB16 __ssub16 | |||
#define __QSUB16 __qsub16 | |||
#define __SHSUB16 __shsub16 | |||
#define __USUB16 __usub16 | |||
#define __UQSUB16 __uqsub16 | |||
#define __UHSUB16 __uhsub16 | |||
#define __SASX __sasx | |||
#define __QASX __qasx | |||
#define __SHASX __shasx | |||
#define __UASX __uasx | |||
#define __UQASX __uqasx | |||
#define __UHASX __uhasx | |||
#define __SSAX __ssax | |||
#define __QSAX __qsax | |||
#define __SHSAX __shsax | |||
#define __USAX __usax | |||
#define __UQSAX __uqsax | |||
#define __UHSAX __uhsax | |||
#define __USAD8 __usad8 | |||
#define __USADA8 __usada8 | |||
#define __SSAT16 __ssat16 | |||
#define __USAT16 __usat16 | |||
#define __UXTB16 __uxtb16 | |||
#define __UXTAB16 __uxtab16 | |||
#define __SXTB16 __sxtb16 | |||
#define __SXTAB16 __sxtab16 | |||
#define __SMUAD __smuad | |||
#define __SMUADX __smuadx | |||
#define __SMLAD __smlad | |||
#define __SMLADX __smladx | |||
#define __SMLALD __smlald | |||
#define __SMLALDX __smlaldx | |||
#define __SMUSD __smusd | |||
#define __SMUSDX __smusdx | |||
#define __SMLSD __smlsd | |||
#define __SMLSDX __smlsdx | |||
#define __SMLSLD __smlsld | |||
#define __SMLSLDX __smlsldx | |||
#define __SEL __sel | |||
#define __QADD __qadd | |||
#define __QSUB __qsub | |||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ | |||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) | |||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ | |||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) | |||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ | |||
((int64_t)(ARG3) << 32) ) >> 32)) | |||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ | |||
/* IAR iccarm specific functions */ | |||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#include <cmsis_iar.h> | |||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ | |||
/* TI CCS specific functions */ | |||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#include <cmsis_ccs.h> | |||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ | |||
/* GNU gcc specific functions */ | |||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
#define __SSAT16(ARG1,ARG2) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1); \ | |||
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ | |||
__RES; \ | |||
}) | |||
#define __USAT16(ARG1,ARG2) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1); \ | |||
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ | |||
__RES; \ | |||
}) | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
#define __SMLALD(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ | |||
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ | |||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ | |||
}) | |||
#define __SMLALDX(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ | |||
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ | |||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ | |||
}) | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
#define __SMLSLD(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ | |||
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ | |||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ | |||
}) | |||
#define __SMLSLDX(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ | |||
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ | |||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ | |||
}) | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); | |||
return(result); | |||
} | |||
#define __PKHBT(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ | |||
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ | |||
__RES; \ | |||
}) | |||
#define __PKHTB(ARG1,ARG2,ARG3) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ | |||
if (ARG3 == 0) \ | |||
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ | |||
else \ | |||
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ | |||
__RES; \ | |||
}) | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) | |||
{ | |||
int32_t result; | |||
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); | |||
return(result); | |||
} | |||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ | |||
/* TASKING carm specific functions */ | |||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
/* not yet supported */ | |||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ | |||
#endif | |||
/*@} end of group CMSIS_SIMD_intrinsics */ | |||
#endif /* __CORE_CM4_SIMD_H */ | |||
#ifdef __cplusplus | |||
} | |||
#endif |
@@ -0,0 +1,636 @@ | |||
/**************************************************************************//** | |||
* @file core_cmFunc.h | |||
* @brief CMSIS Cortex-M Core Function Access Header File | |||
* @version V3.20 | |||
* @date 25. February 2013 | |||
* | |||
* @note | |||
* | |||
******************************************************************************/ | |||
/* Copyright (c) 2009 - 2013 ARM LIMITED | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions are met: | |||
- Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | |||
- Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution. | |||
- Neither the name of ARM nor the names of its contributors may be used | |||
to endorse or promote products derived from this software without | |||
specific prior written permission. | |||
* | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE | |||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | |||
---------------------------------------------------------------------------*/ | |||
#ifndef __CORE_CMFUNC_H | |||
#define __CORE_CMFUNC_H | |||
/* ########################### Core Function Access ########################### */ | |||
/** \ingroup CMSIS_Core_FunctionInterface | |||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions | |||
@{ | |||
*/ | |||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ | |||
/* ARM armcc specific functions */ | |||
#if (__ARMCC_VERSION < 400677) | |||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!" | |||
#endif | |||
/* intrinsic void __enable_irq(); */ | |||
/* intrinsic void __disable_irq(); */ | |||
/** \brief Get Control Register | |||
This function returns the content of the Control Register. | |||
\return Control Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_CONTROL(void) | |||
{ | |||
register uint32_t __regControl __ASM("control"); | |||
return(__regControl); | |||
} | |||
/** \brief Set Control Register | |||
This function writes the given value to the Control Register. | |||
\param [in] control Control Register value to set | |||
*/ | |||
__STATIC_INLINE void __set_CONTROL(uint32_t control) | |||
{ | |||
register uint32_t __regControl __ASM("control"); | |||
__regControl = control; | |||
} | |||
/** \brief Get IPSR Register | |||
This function returns the content of the IPSR Register. | |||
\return IPSR Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_IPSR(void) | |||
{ | |||
register uint32_t __regIPSR __ASM("ipsr"); | |||
return(__regIPSR); | |||
} | |||
/** \brief Get APSR Register | |||
This function returns the content of the APSR Register. | |||
\return APSR Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_APSR(void) | |||
{ | |||
register uint32_t __regAPSR __ASM("apsr"); | |||
return(__regAPSR); | |||
} | |||
/** \brief Get xPSR Register | |||
This function returns the content of the xPSR Register. | |||
\return xPSR Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_xPSR(void) | |||
{ | |||
register uint32_t __regXPSR __ASM("xpsr"); | |||
return(__regXPSR); | |||
} | |||
/** \brief Get Process Stack Pointer | |||
This function returns the current value of the Process Stack Pointer (PSP). | |||
\return PSP Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_PSP(void) | |||
{ | |||
register uint32_t __regProcessStackPointer __ASM("psp"); | |||
return(__regProcessStackPointer); | |||
} | |||
/** \brief Set Process Stack Pointer | |||
This function assigns the given value to the Process Stack Pointer (PSP). | |||
\param [in] topOfProcStack Process Stack Pointer value to set | |||
*/ | |||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) | |||
{ | |||
register uint32_t __regProcessStackPointer __ASM("psp"); | |||
__regProcessStackPointer = topOfProcStack; | |||
} | |||
/** \brief Get Main Stack Pointer | |||
This function returns the current value of the Main Stack Pointer (MSP). | |||
\return MSP Register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_MSP(void) | |||
{ | |||
register uint32_t __regMainStackPointer __ASM("msp"); | |||
return(__regMainStackPointer); | |||
} | |||
/** \brief Set Main Stack Pointer | |||
This function assigns the given value to the Main Stack Pointer (MSP). | |||
\param [in] topOfMainStack Main Stack Pointer value to set | |||
*/ | |||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) | |||
{ | |||
register uint32_t __regMainStackPointer __ASM("msp"); | |||
__regMainStackPointer = topOfMainStack; | |||
} | |||
/** \brief Get Priority Mask | |||
This function returns the current state of the priority mask bit from the Priority Mask Register. | |||
\return Priority Mask value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_PRIMASK(void) | |||
{ | |||
register uint32_t __regPriMask __ASM("primask"); | |||
return(__regPriMask); | |||
} | |||
/** \brief Set Priority Mask | |||
This function assigns the given value to the Priority Mask Register. | |||
\param [in] priMask Priority Mask | |||
*/ | |||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) | |||
{ | |||
register uint32_t __regPriMask __ASM("primask"); | |||
__regPriMask = (priMask); | |||
} | |||
#if (__CORTEX_M >= 0x03) | |||
/** \brief Enable FIQ | |||
This function enables FIQ interrupts by clearing the F-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
#define __enable_fault_irq __enable_fiq | |||
/** \brief Disable FIQ | |||
This function disables FIQ interrupts by setting the F-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
#define __disable_fault_irq __disable_fiq | |||
/** \brief Get Base Priority | |||
This function returns the current value of the Base Priority register. | |||
\return Base Priority register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_BASEPRI(void) | |||
{ | |||
register uint32_t __regBasePri __ASM("basepri"); | |||
return(__regBasePri); | |||
} | |||
/** \brief Set Base Priority | |||
This function assigns the given value to the Base Priority register. | |||
\param [in] basePri Base Priority value to set | |||
*/ | |||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) | |||
{ | |||
register uint32_t __regBasePri __ASM("basepri"); | |||
__regBasePri = (basePri & 0xff); | |||
} | |||
/** \brief Get Fault Mask | |||
This function returns the current value of the Fault Mask register. | |||
\return Fault Mask register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_FAULTMASK(void) | |||
{ | |||
register uint32_t __regFaultMask __ASM("faultmask"); | |||
return(__regFaultMask); | |||
} | |||
/** \brief Set Fault Mask | |||
This function assigns the given value to the Fault Mask register. | |||
\param [in] faultMask Fault Mask value to set | |||
*/ | |||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) | |||
{ | |||
register uint32_t __regFaultMask __ASM("faultmask"); | |||
__regFaultMask = (faultMask & (uint32_t)1); | |||
} | |||
#endif /* (__CORTEX_M >= 0x03) */ | |||
#if (__CORTEX_M == 0x04) | |||
/** \brief Get FPSCR | |||
This function returns the current value of the Floating Point Status/Control register. | |||
\return Floating Point Status/Control register value | |||
*/ | |||
__STATIC_INLINE uint32_t __get_FPSCR(void) | |||
{ | |||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) | |||
register uint32_t __regfpscr __ASM("fpscr"); | |||
return(__regfpscr); | |||
#else | |||
return(0); | |||
#endif | |||
} | |||
/** \brief Set FPSCR | |||
This function assigns the given value to the Floating Point Status/Control register. | |||
\param [in] fpscr Floating Point Status/Control value to set | |||
*/ | |||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) | |||
{ | |||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) | |||
register uint32_t __regfpscr __ASM("fpscr"); | |||
__regfpscr = (fpscr); | |||
#endif | |||
} | |||
#endif /* (__CORTEX_M == 0x04) */ | |||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ | |||
/* IAR iccarm specific functions */ | |||
#include <cmsis_iar.h> | |||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ | |||
/* TI CCS specific functions */ | |||
#include <cmsis_ccs.h> | |||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ | |||
/* GNU gcc specific functions */ | |||
/** \brief Enable IRQ Interrupts | |||
This function enables IRQ interrupts by clearing the I-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) | |||
{ | |||
__ASM volatile ("cpsie i" : : : "memory"); | |||
} | |||
/** \brief Disable IRQ Interrupts | |||
This function disables IRQ interrupts by setting the I-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) | |||
{ | |||
__ASM volatile ("cpsid i" : : : "memory"); | |||
} | |||
/** \brief Get Control Register | |||
This function returns the content of the Control Register. | |||
\return Control Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, control" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Control Register | |||
This function writes the given value to the Control Register. | |||
\param [in] control Control Register value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) | |||
{ | |||
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); | |||
} | |||
/** \brief Get IPSR Register | |||
This function returns the content of the IPSR Register. | |||
\return IPSR Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Get APSR Register | |||
This function returns the content of the APSR Register. | |||
\return APSR Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, apsr" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Get xPSR Register | |||
This function returns the content of the xPSR Register. | |||
\return xPSR Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Get Process Stack Pointer | |||
This function returns the current value of the Process Stack Pointer (PSP). | |||
\return PSP Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) | |||
{ | |||
register uint32_t result; | |||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Process Stack Pointer | |||
This function assigns the given value to the Process Stack Pointer (PSP). | |||
\param [in] topOfProcStack Process Stack Pointer value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) | |||
{ | |||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); | |||
} | |||
/** \brief Get Main Stack Pointer | |||
This function returns the current value of the Main Stack Pointer (MSP). | |||
\return MSP Register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) | |||
{ | |||
register uint32_t result; | |||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Main Stack Pointer | |||
This function assigns the given value to the Main Stack Pointer (MSP). | |||
\param [in] topOfMainStack Main Stack Pointer value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) | |||
{ | |||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); | |||
} | |||
/** \brief Get Priority Mask | |||
This function returns the current state of the priority mask bit from the Priority Mask Register. | |||
\return Priority Mask value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, primask" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Priority Mask | |||
This function assigns the given value to the Priority Mask Register. | |||
\param [in] priMask Priority Mask | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) | |||
{ | |||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); | |||
} | |||
#if (__CORTEX_M >= 0x03) | |||
/** \brief Enable FIQ | |||
This function enables FIQ interrupts by clearing the F-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) | |||
{ | |||
__ASM volatile ("cpsie f" : : : "memory"); | |||
} | |||
/** \brief Disable FIQ | |||
This function disables FIQ interrupts by setting the F-bit in the CPSR. | |||
Can only be executed in Privileged modes. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) | |||
{ | |||
__ASM volatile ("cpsid f" : : : "memory"); | |||
} | |||
/** \brief Get Base Priority | |||
This function returns the current value of the Base Priority register. | |||
\return Base Priority register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Base Priority | |||
This function assigns the given value to the Base Priority register. | |||
\param [in] basePri Base Priority value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) | |||
{ | |||
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); | |||
} | |||
/** \brief Get Fault Mask | |||
This function returns the current value of the Fault Mask register. | |||
\return Fault Mask register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) ); | |||
return(result); | |||
} | |||
/** \brief Set Fault Mask | |||
This function assigns the given value to the Fault Mask register. | |||
\param [in] faultMask Fault Mask value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) | |||
{ | |||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); | |||
} | |||
#endif /* (__CORTEX_M >= 0x03) */ | |||
#if (__CORTEX_M == 0x04) | |||
/** \brief Get FPSCR | |||
This function returns the current value of the Floating Point Status/Control register. | |||
\return Floating Point Status/Control register value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) | |||
{ | |||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) | |||
uint32_t result; | |||
/* Empty asm statement works as a scheduling barrier */ | |||
__ASM volatile (""); | |||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); | |||
__ASM volatile (""); | |||
return(result); | |||
#else | |||
return(0); | |||
#endif | |||
} | |||
/** \brief Set FPSCR | |||
This function assigns the given value to the Floating Point Status/Control register. | |||
\param [in] fpscr Floating Point Status/Control value to set | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) | |||
{ | |||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) | |||
/* Empty asm statement works as a scheduling barrier */ | |||
__ASM volatile (""); | |||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); | |||
__ASM volatile (""); | |||
#endif | |||
} | |||
#endif /* (__CORTEX_M == 0x04) */ | |||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ | |||
/* TASKING carm specific functions */ | |||
/* | |||
* The CMSIS functions have been implemented as intrinsics in the compiler. | |||
* Please use "carm -?i" to get an up to date list of all instrinsics, | |||
* Including the CMSIS ones. | |||
*/ | |||
#endif | |||
/*@} end of CMSIS_Core_RegAccFunctions */ | |||
#endif /* __CORE_CMFUNC_H */ |
@@ -0,0 +1,688 @@ | |||
/**************************************************************************//** | |||
* @file core_cmInstr.h | |||
* @brief CMSIS Cortex-M Core Instruction Access Header File | |||
* @version V3.20 | |||
* @date 05. March 2013 | |||
* | |||
* @note | |||
* | |||
******************************************************************************/ | |||
/* Copyright (c) 2009 - 2013 ARM LIMITED | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions are met: | |||
- Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | |||
- Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution. | |||
- Neither the name of ARM nor the names of its contributors may be used | |||
to endorse or promote products derived from this software without | |||
specific prior written permission. | |||
* | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE | |||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
POSSIBILITY OF SUCH DAMAGE. | |||
---------------------------------------------------------------------------*/ | |||
#ifndef __CORE_CMINSTR_H | |||
#define __CORE_CMINSTR_H | |||
/* ########################## Core Instruction Access ######################### */ | |||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface | |||
Access to dedicated instructions | |||
@{ | |||
*/ | |||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ | |||
/* ARM armcc specific functions */ | |||
#if (__ARMCC_VERSION < 400677) | |||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!" | |||
#endif | |||
/** \brief No Operation | |||
No Operation does nothing. This instruction can be used for code alignment purposes. | |||
*/ | |||
#define __NOP __nop | |||
/** \brief Wait For Interrupt | |||
Wait For Interrupt is a hint instruction that suspends execution | |||
until one of a number of events occurs. | |||
*/ | |||
#define __WFI __wfi | |||
/** \brief Wait For Event | |||
Wait For Event is a hint instruction that permits the processor to enter | |||
a low-power state until one of a number of events occurs. | |||
*/ | |||
#define __WFE __wfe | |||
/** \brief Send Event | |||
Send Event is a hint instruction. It causes an event to be signaled to the CPU. | |||
*/ | |||
#define __SEV __sev | |||
/** \brief Instruction Synchronization Barrier | |||
Instruction Synchronization Barrier flushes the pipeline in the processor, | |||
so that all instructions following the ISB are fetched from cache or | |||
memory, after the instruction has been completed. | |||
*/ | |||
#define __ISB() __isb(0xF) | |||
/** \brief Data Synchronization Barrier | |||
This function acts as a special kind of Data Memory Barrier. | |||
It completes when all explicit memory accesses before this instruction complete. | |||
*/ | |||
#define __DSB() __dsb(0xF) | |||
/** \brief Data Memory Barrier | |||
This function ensures the apparent order of the explicit memory operations before | |||
and after the instruction, without ensuring their completion. | |||
*/ | |||
#define __DMB() __dmb(0xF) | |||
/** \brief Reverse byte order (32 bit) | |||
This function reverses the byte order in integer value. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
#define __REV __rev | |||
/** \brief Reverse byte order (16 bit) | |||
This function reverses the byte order in two unsigned short values. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
#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 in signed short value | |||
This function reverses the byte order in a signed short value with sign extension to integer. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
#ifndef __NO_EMBEDDED_ASM | |||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) | |||
{ | |||
revsh r0, r0 | |||
bx lr | |||
} | |||
#endif | |||
/** \brief Rotate Right in unsigned value (32 bit) | |||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | |||
\param [in] value Value to rotate | |||
\param [in] value Number of Bits to rotate | |||
\return Rotated value | |||
*/ | |||
#define __ROR __ror | |||
/** \brief Breakpoint | |||
This function 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) | |||
#if (__CORTEX_M >= 0x03) | |||
/** \brief Reverse bit order of value | |||
This function reverses the bit order of the given value. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
#define __RBIT __rbit | |||
/** \brief LDR Exclusive (8 bit) | |||
This function performs a exclusive LDR command for 8 bit value. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint8_t at (*ptr) | |||
*/ | |||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) | |||
/** \brief LDR Exclusive (16 bit) | |||
This function performs a exclusive LDR command for 16 bit values. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint16_t at (*ptr) | |||
*/ | |||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) | |||
/** \brief LDR Exclusive (32 bit) | |||
This function performs a exclusive LDR command for 32 bit values. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint32_t at (*ptr) | |||
*/ | |||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) | |||
/** \brief STR Exclusive (8 bit) | |||
This function performs a exclusive STR command for 8 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
#define __STREXB(value, ptr) __strex(value, ptr) | |||
/** \brief STR Exclusive (16 bit) | |||
This function performs a exclusive STR command for 16 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
#define __STREXH(value, ptr) __strex(value, ptr) | |||
/** \brief STR Exclusive (32 bit) | |||
This function performs a exclusive STR command for 32 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
#define __STREXW(value, ptr) __strex(value, ptr) | |||
/** \brief Remove the exclusive lock | |||
This function removes the exclusive lock which is created by LDREX. | |||
*/ | |||
#define __CLREX __clrex | |||
/** \brief Signed Saturate | |||
This function saturates a signed value. | |||
\param [in] value Value to be saturated | |||
\param [in] sat Bit position to saturate to (1..32) | |||
\return Saturated value | |||
*/ | |||
#define __SSAT __ssat | |||
/** \brief Unsigned Saturate | |||
This function saturates an unsigned value. | |||
\param [in] value Value to be saturated | |||
\param [in] sat Bit position to saturate to (0..31) | |||
\return Saturated value | |||
*/ | |||
#define __USAT __usat | |||
/** \brief Count leading zeros | |||
This function counts the number of leading zeros of a data value. | |||
\param [in] value Value to count the leading zeros | |||
\return number of leading zeros in value | |||
*/ | |||
#define __CLZ __clz | |||
#endif /* (__CORTEX_M >= 0x03) */ | |||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ | |||
/* IAR iccarm specific functions */ | |||
#include <cmsis_iar.h> | |||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ | |||
/* TI CCS specific functions */ | |||
#include <cmsis_ccs.h> | |||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ | |||
/* GNU gcc specific functions */ | |||
/* Define macros for porting to both thumb1 and thumb2. | |||
* For thumb1, use low register (r0-r7), specified by constrant "l" | |||
* Otherwise, use general registers, specified by constrant "r" */ | |||
#if defined (__thumb__) && !defined (__thumb2__) | |||
#define __CMSIS_GCC_OUT_REG(r) "=l" (r) | |||
#define __CMSIS_GCC_USE_REG(r) "l" (r) | |||
#else | |||
#define __CMSIS_GCC_OUT_REG(r) "=r" (r) | |||
#define __CMSIS_GCC_USE_REG(r) "r" (r) | |||
#endif | |||
/** \brief No Operation | |||
No Operation does nothing. This instruction can be used for code alignment purposes. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) | |||
{ | |||
__ASM volatile ("nop"); | |||
} | |||
/** \brief Wait For Interrupt | |||
Wait For Interrupt is a hint instruction that suspends execution | |||
until one of a number of events occurs. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) | |||
{ | |||
__ASM volatile ("wfi"); | |||
} | |||
/** \brief Wait For Event | |||
Wait For Event is a hint instruction that permits the processor to enter | |||
a low-power state until one of a number of events occurs. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) | |||
{ | |||
__ASM volatile ("wfe"); | |||
} | |||
/** \brief Send Event | |||
Send Event is a hint instruction. It causes an event to be signaled to the CPU. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) | |||
{ | |||
__ASM volatile ("sev"); | |||
} | |||
/** \brief Instruction Synchronization Barrier | |||
Instruction Synchronization Barrier flushes the pipeline in the processor, | |||
so that all instructions following the ISB are fetched from cache or | |||
memory, after the instruction has been completed. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) | |||
{ | |||
__ASM volatile ("isb"); | |||
} | |||
/** \brief Data Synchronization Barrier | |||
This function acts as a special kind of Data Memory Barrier. | |||
It completes when all explicit memory accesses before this instruction complete. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) | |||
{ | |||
__ASM volatile ("dsb"); | |||
} | |||
/** \brief Data Memory Barrier | |||
This function ensures the apparent order of the explicit memory operations before | |||
and after the instruction, without ensuring their completion. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) | |||
{ | |||
__ASM volatile ("dmb"); | |||
} | |||
/** \brief Reverse byte order (32 bit) | |||
This function reverses the byte order in integer value. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) | |||
{ | |||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | |||
return __builtin_bswap32(value); | |||
#else | |||
uint32_t result; | |||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); | |||
return(result); | |||
#endif | |||
} | |||
/** \brief Reverse byte order (16 bit) | |||
This function reverses the byte order in two unsigned short values. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); | |||
return(result); | |||
} | |||
/** \brief Reverse byte order in signed short value | |||
This function reverses the byte order in a signed short value with sign extension to integer. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) | |||
{ | |||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | |||
return (short)__builtin_bswap16(value); | |||
#else | |||
uint32_t result; | |||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); | |||
return(result); | |||
#endif | |||
} | |||
/** \brief Rotate Right in unsigned value (32 bit) | |||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. | |||
\param [in] value Value to rotate | |||
\param [in] value Number of Bits to rotate | |||
\return Rotated value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) | |||
{ | |||
return (op1 >> op2) | (op1 << (32 - op2)); | |||
} | |||
/** \brief Breakpoint | |||
This function 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) __ASM volatile ("bkpt "#value) | |||
#if (__CORTEX_M >= 0x03) | |||
/** \brief Reverse bit order of value | |||
This function reverses the bit order of the given value. | |||
\param [in] value Value to reverse | |||
\return Reversed value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); | |||
return(result); | |||
} | |||
/** \brief LDR Exclusive (8 bit) | |||
This function performs a exclusive LDR command for 8 bit value. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint8_t at (*ptr) | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) | |||
{ | |||
uint32_t result; | |||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | |||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); | |||
#else | |||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not | |||
accepted by assembler. So has to use following less efficient pattern. | |||
*/ | |||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); | |||
#endif | |||
return(result); | |||
} | |||
/** \brief LDR Exclusive (16 bit) | |||
This function performs a exclusive LDR command for 16 bit values. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint16_t at (*ptr) | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) | |||
{ | |||
uint32_t result; | |||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | |||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); | |||
#else | |||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not | |||
accepted by assembler. So has to use following less efficient pattern. | |||
*/ | |||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); | |||
#endif | |||
return(result); | |||
} | |||
/** \brief LDR Exclusive (32 bit) | |||
This function performs a exclusive LDR command for 32 bit values. | |||
\param [in] ptr Pointer to data | |||
\return value of type uint32_t at (*ptr) | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); | |||
return(result); | |||
} | |||
/** \brief STR Exclusive (8 bit) | |||
This function performs a exclusive STR command for 8 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); | |||
return(result); | |||
} | |||
/** \brief STR Exclusive (16 bit) | |||
This function performs a exclusive STR command for 16 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); | |||
return(result); | |||
} | |||
/** \brief STR Exclusive (32 bit) | |||
This function performs a exclusive STR command for 32 bit values. | |||
\param [in] value Value to store | |||
\param [in] ptr Pointer to location | |||
\return 0 Function succeeded | |||
\return 1 Function failed | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); | |||
return(result); | |||
} | |||
/** \brief Remove the exclusive lock | |||
This function removes the exclusive lock which is created by LDREX. | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) | |||
{ | |||
__ASM volatile ("clrex" ::: "memory"); | |||
} | |||
/** \brief Signed Saturate | |||
This function saturates a signed value. | |||
\param [in] value Value to be saturated | |||
\param [in] sat Bit position to saturate to (1..32) | |||
\return Saturated value | |||
*/ | |||
#define __SSAT(ARG1,ARG2) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1); \ | |||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ | |||
__RES; \ | |||
}) | |||
/** \brief Unsigned Saturate | |||
This function saturates an unsigned value. | |||
\param [in] value Value to be saturated | |||
\param [in] sat Bit position to saturate to (0..31) | |||
\return Saturated value | |||
*/ | |||
#define __USAT(ARG1,ARG2) \ | |||
({ \ | |||
uint32_t __RES, __ARG1 = (ARG1); \ | |||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ | |||
__RES; \ | |||
}) | |||
/** \brief Count leading zeros | |||
This function counts the number of leading zeros of a data value. | |||
\param [in] value Value to count the leading zeros | |||
\return number of leading zeros in value | |||
*/ | |||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) | |||
{ | |||
uint32_t result; | |||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); | |||
return(result); | |||
} | |||
#endif /* (__CORTEX_M >= 0x03) */ | |||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ | |||
/* TASKING carm specific functions */ | |||
/* | |||
* The CMSIS functions have been implemented as intrinsics in the compiler. | |||
* Please use "carm -?i" to get an up to date list of all intrinsics, | |||
* Including the CMSIS ones. | |||
*/ | |||
#endif | |||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ | |||
#endif /* __CORE_CMINSTR_H */ |
@@ -0,0 +1,178 @@ | |||
/** | |||
****************************************************************************** | |||
* @file misc.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains all the functions prototypes for the miscellaneous | |||
* firmware library functions (add-on to CMSIS functions). | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __MISC_H | |||
#define __MISC_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup MISC | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
/** | |||
* @brief NVIC Init Structure definition | |||
*/ | |||
typedef struct | |||
{ | |||
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. | |||
This parameter can be an enumerator of @ref IRQn_Type | |||
enumeration (For the complete STM32 Devices IRQ Channels | |||
list, please refer to stm32f4xx.h file) */ | |||
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel | |||
specified in NVIC_IRQChannel. This parameter can be a value | |||
between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table | |||
A lower priority value indicates a higher priority */ | |||
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified | |||
in NVIC_IRQChannel. This parameter can be a value | |||
between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table | |||
A lower priority value indicates a higher priority */ | |||
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel | |||
will be enabled or disabled. | |||
This parameter can be set either to ENABLE or DISABLE */ | |||
} NVIC_InitTypeDef; | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup MISC_Exported_Constants | |||
* @{ | |||
*/ | |||
/** @defgroup MISC_Vector_Table_Base | |||
* @{ | |||
*/ | |||
#define NVIC_VectTab_RAM ((uint32_t)0x20000000) | |||
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000) | |||
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ | |||
((VECTTAB) == NVIC_VectTab_FLASH)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup MISC_System_Low_Power | |||
* @{ | |||
*/ | |||
#define NVIC_LP_SEVONPEND ((uint8_t)0x10) | |||
#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) | |||
#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) | |||
#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ | |||
((LP) == NVIC_LP_SLEEPDEEP) || \ | |||
((LP) == NVIC_LP_SLEEPONEXIT)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup MISC_Preemption_Priority_Group | |||
* @{ | |||
*/ | |||
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority | |||
4 bits for subpriority */ | |||
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority | |||
3 bits for subpriority */ | |||
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority | |||
2 bits for subpriority */ | |||
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority | |||
1 bits for subpriority */ | |||
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority | |||
0 bits for subpriority */ | |||
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ | |||
((GROUP) == NVIC_PriorityGroup_1) || \ | |||
((GROUP) == NVIC_PriorityGroup_2) || \ | |||
((GROUP) == NVIC_PriorityGroup_3) || \ | |||
((GROUP) == NVIC_PriorityGroup_4)) | |||
#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) | |||
#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) | |||
#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup MISC_SysTick_clock_source | |||
* @{ | |||
*/ | |||
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) | |||
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) | |||
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ | |||
((SOURCE) == SysTick_CLKSource_HCLK_Div8)) | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); | |||
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); | |||
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); | |||
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); | |||
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* __MISC_H */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,183 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_exti.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains all the functions prototypes for the EXTI firmware | |||
* library. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_EXTI_H | |||
#define __STM32F4xx_EXTI_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup EXTI | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
/** | |||
* @brief EXTI mode enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
EXTI_Mode_Interrupt = 0x00, | |||
EXTI_Mode_Event = 0x04 | |||
}EXTIMode_TypeDef; | |||
#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event)) | |||
/** | |||
* @brief EXTI Trigger enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
EXTI_Trigger_Rising = 0x08, | |||
EXTI_Trigger_Falling = 0x0C, | |||
EXTI_Trigger_Rising_Falling = 0x10 | |||
}EXTITrigger_TypeDef; | |||
#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \ | |||
((TRIGGER) == EXTI_Trigger_Falling) || \ | |||
((TRIGGER) == EXTI_Trigger_Rising_Falling)) | |||
/** | |||
* @brief EXTI Init Structure definition | |||
*/ | |||
typedef struct | |||
{ | |||
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled. | |||
This parameter can be any combination value of @ref EXTI_Lines */ | |||
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines. | |||
This parameter can be a value of @ref EXTIMode_TypeDef */ | |||
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. | |||
This parameter can be a value of @ref EXTITrigger_TypeDef */ | |||
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines. | |||
This parameter can be set either to ENABLE or DISABLE */ | |||
}EXTI_InitTypeDef; | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup EXTI_Exported_Constants | |||
* @{ | |||
*/ | |||
/** @defgroup EXTI_Lines | |||
* @{ | |||
*/ | |||
#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */ | |||
#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */ | |||
#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */ | |||
#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */ | |||
#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */ | |||
#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */ | |||
#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */ | |||
#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */ | |||
#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */ | |||
#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */ | |||
#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */ | |||
#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */ | |||
#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */ | |||
#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */ | |||
#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */ | |||
#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */ | |||
#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */ | |||
#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */ | |||
#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */ | |||
#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ | |||
#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event */ | |||
#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */ | |||
#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 Connected to the RTC Wakeup event */ | |||
#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF800000) == 0x00) && ((LINE) != (uint16_t)0x00)) | |||
#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \ | |||
((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \ | |||
((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \ | |||
((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \ | |||
((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \ | |||
((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \ | |||
((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \ | |||
((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \ | |||
((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \ | |||
((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \ | |||
((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) ||\ | |||
((LINE) == EXTI_Line22)) | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
/* Function used to set the EXTI configuration to the default reset state *****/ | |||
void EXTI_DeInit(void); | |||
/* Initialization and Configuration functions *********************************/ | |||
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); | |||
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct); | |||
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line); | |||
/* Interrupts and flags management functions **********************************/ | |||
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line); | |||
void EXTI_ClearFlag(uint32_t EXTI_Line); | |||
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); | |||
void EXTI_ClearITPendingBit(uint32_t EXTI_Line); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* __STM32F4xx_EXTI_H */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,502 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_gpio.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains all the functions prototypes for the GPIO firmware | |||
* library. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_GPIO_H | |||
#define __STM32F4xx_GPIO_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup GPIO | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ | |||
((PERIPH) == GPIOB) || \ | |||
((PERIPH) == GPIOC) || \ | |||
((PERIPH) == GPIOD) || \ | |||
((PERIPH) == GPIOE) || \ | |||
((PERIPH) == GPIOF) || \ | |||
((PERIPH) == GPIOG) || \ | |||
((PERIPH) == GPIOH) || \ | |||
((PERIPH) == GPIOI) || \ | |||
((PERIPH) == GPIOJ) || \ | |||
((PERIPH) == GPIOK)) | |||
/** | |||
* @brief GPIO Configuration Mode enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ | |||
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ | |||
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ | |||
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ | |||
}GPIOMode_TypeDef; | |||
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ | |||
((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) | |||
/** | |||
* @brief GPIO Output type enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
GPIO_OType_PP = 0x00, | |||
GPIO_OType_OD = 0x01 | |||
}GPIOOType_TypeDef; | |||
#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) | |||
/** | |||
* @brief GPIO Output Maximum frequency enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
GPIO_Low_Speed = 0x00, /*!< Low speed */ | |||
GPIO_Medium_Speed = 0x01, /*!< Medium speed */ | |||
GPIO_Fast_Speed = 0x02, /*!< Fast speed */ | |||
GPIO_High_Speed = 0x03 /*!< High speed */ | |||
}GPIOSpeed_TypeDef; | |||
/* Add legacy definition */ | |||
#define GPIO_Speed_2MHz GPIO_Low_Speed | |||
#define GPIO_Speed_25MHz GPIO_Medium_Speed | |||
#define GPIO_Speed_50MHz GPIO_Fast_Speed | |||
#define GPIO_Speed_100MHz GPIO_High_Speed | |||
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \ | |||
((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed)) | |||
/** | |||
* @brief GPIO Configuration PullUp PullDown enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
GPIO_PuPd_NOPULL = 0x00, | |||
GPIO_PuPd_UP = 0x01, | |||
GPIO_PuPd_DOWN = 0x02 | |||
}GPIOPuPd_TypeDef; | |||
#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ | |||
((PUPD) == GPIO_PuPd_DOWN)) | |||
/** | |||
* @brief GPIO Bit SET and Bit RESET enumeration | |||
*/ | |||
typedef enum | |||
{ | |||
Bit_RESET = 0, | |||
Bit_SET | |||
}BitAction; | |||
#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) | |||
/** | |||
* @brief GPIO Init structure definition | |||
*/ | |||
typedef struct | |||
{ | |||
uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. | |||
This parameter can be any value of @ref GPIO_pins_define */ | |||
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. | |||
This parameter can be a value of @ref GPIOMode_TypeDef */ | |||
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. | |||
This parameter can be a value of @ref GPIOSpeed_TypeDef */ | |||
GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. | |||
This parameter can be a value of @ref GPIOOType_TypeDef */ | |||
GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. | |||
This parameter can be a value of @ref GPIOPuPd_TypeDef */ | |||
}GPIO_InitTypeDef; | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup GPIO_Exported_Constants | |||
* @{ | |||
*/ | |||
/** @defgroup GPIO_pins_define | |||
* @{ | |||
*/ | |||
#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ | |||
#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ | |||
#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ | |||
#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ | |||
#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ | |||
#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ | |||
#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ | |||
#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ | |||
#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ | |||
#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ | |||
#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ | |||
#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ | |||
#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ | |||
#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ | |||
#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ | |||
#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ | |||
#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ | |||
#define GPIO_PIN_MASK ((uint32_t)0x0000FFFF) /* PIN mask for assert test */ | |||
#define IS_GPIO_PIN(PIN) (((PIN) & GPIO_PIN_MASK ) != (uint32_t)0x00) | |||
#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ | |||
((PIN) == GPIO_Pin_1) || \ | |||
((PIN) == GPIO_Pin_2) || \ | |||
((PIN) == GPIO_Pin_3) || \ | |||
((PIN) == GPIO_Pin_4) || \ | |||
((PIN) == GPIO_Pin_5) || \ | |||
((PIN) == GPIO_Pin_6) || \ | |||
((PIN) == GPIO_Pin_7) || \ | |||
((PIN) == GPIO_Pin_8) || \ | |||
((PIN) == GPIO_Pin_9) || \ | |||
((PIN) == GPIO_Pin_10) || \ | |||
((PIN) == GPIO_Pin_11) || \ | |||
((PIN) == GPIO_Pin_12) || \ | |||
((PIN) == GPIO_Pin_13) || \ | |||
((PIN) == GPIO_Pin_14) || \ | |||
((PIN) == GPIO_Pin_15)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup GPIO_Pin_sources | |||
* @{ | |||
*/ | |||
#define GPIO_PinSource0 ((uint8_t)0x00) | |||
#define GPIO_PinSource1 ((uint8_t)0x01) | |||
#define GPIO_PinSource2 ((uint8_t)0x02) | |||
#define GPIO_PinSource3 ((uint8_t)0x03) | |||
#define GPIO_PinSource4 ((uint8_t)0x04) | |||
#define GPIO_PinSource5 ((uint8_t)0x05) | |||
#define GPIO_PinSource6 ((uint8_t)0x06) | |||
#define GPIO_PinSource7 ((uint8_t)0x07) | |||
#define GPIO_PinSource8 ((uint8_t)0x08) | |||
#define GPIO_PinSource9 ((uint8_t)0x09) | |||
#define GPIO_PinSource10 ((uint8_t)0x0A) | |||
#define GPIO_PinSource11 ((uint8_t)0x0B) | |||
#define GPIO_PinSource12 ((uint8_t)0x0C) | |||
#define GPIO_PinSource13 ((uint8_t)0x0D) | |||
#define GPIO_PinSource14 ((uint8_t)0x0E) | |||
#define GPIO_PinSource15 ((uint8_t)0x0F) | |||
#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ | |||
((PINSOURCE) == GPIO_PinSource1) || \ | |||
((PINSOURCE) == GPIO_PinSource2) || \ | |||
((PINSOURCE) == GPIO_PinSource3) || \ | |||
((PINSOURCE) == GPIO_PinSource4) || \ | |||
((PINSOURCE) == GPIO_PinSource5) || \ | |||
((PINSOURCE) == GPIO_PinSource6) || \ | |||
((PINSOURCE) == GPIO_PinSource7) || \ | |||
((PINSOURCE) == GPIO_PinSource8) || \ | |||
((PINSOURCE) == GPIO_PinSource9) || \ | |||
((PINSOURCE) == GPIO_PinSource10) || \ | |||
((PINSOURCE) == GPIO_PinSource11) || \ | |||
((PINSOURCE) == GPIO_PinSource12) || \ | |||
((PINSOURCE) == GPIO_PinSource13) || \ | |||
((PINSOURCE) == GPIO_PinSource14) || \ | |||
((PINSOURCE) == GPIO_PinSource15)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup GPIO_Alternat_function_selection_define | |||
* @{ | |||
*/ | |||
/** | |||
* @brief AF 0 selection | |||
*/ | |||
#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ | |||
#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ | |||
#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ | |||
#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ | |||
#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ | |||
/** | |||
* @brief AF 1 selection | |||
*/ | |||
#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ | |||
#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ | |||
/** | |||
* @brief AF 2 selection | |||
*/ | |||
#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ | |||
#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ | |||
#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ | |||
/** | |||
* @brief AF 3 selection | |||
*/ | |||
#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ | |||
#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ | |||
#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ | |||
#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ | |||
/** | |||
* @brief AF 4 selection | |||
*/ | |||
#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ | |||
#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ | |||
#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ | |||
/** | |||
* @brief AF 5 selection | |||
*/ | |||
#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ | |||
#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ | |||
#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE Devices) */ | |||
#define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */ | |||
#define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ | |||
#define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ | |||
/** | |||
* @brief AF 6 selection | |||
*/ | |||
#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ | |||
#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F411xE Devices) */ | |||
#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */ | |||
#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F411xE Devices) */ | |||
#define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ | |||
/** | |||
* @brief AF 7 selection | |||
*/ | |||
#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ | |||
#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ | |||
#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ | |||
#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */ | |||
/** | |||
* @brief AF 7 selection Legacy | |||
*/ | |||
#define GPIO_AF_I2S3ext GPIO_AF7_SPI3 | |||
/** | |||
* @brief AF 8 selection | |||
*/ | |||
#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ | |||
#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ | |||
#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ | |||
#define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ | |||
#define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ | |||
/** | |||
* @brief AF 9 selection | |||
*/ | |||
#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ | |||
#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ | |||
#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ | |||
#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ | |||
#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ | |||
#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F411xE Devices) */ | |||
#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE Devices) */ | |||
/** | |||
* @brief AF 10 selection | |||
*/ | |||
#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ | |||
#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ | |||
/** | |||
* @brief AF 11 selection | |||
*/ | |||
#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ | |||
/** | |||
* @brief AF 12 selection | |||
*/ | |||
#if defined (STM32F40_41xxx) | |||
#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
#define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ | |||
#endif /* STM32F427_437xx || STM32F429_439xx */ | |||
#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ | |||
#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ | |||
/** | |||
* @brief AF 13 selection | |||
*/ | |||
#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ | |||
/** | |||
* @brief AF 14 selection | |||
*/ | |||
#define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ | |||
/** | |||
* @brief AF 15 selection | |||
*/ | |||
#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ | |||
#if defined (STM32F40_41xxx) | |||
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ | |||
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ | |||
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ | |||
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ | |||
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ | |||
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ | |||
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ | |||
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ | |||
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ | |||
((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ | |||
((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ | |||
((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ | |||
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ | |||
((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ | |||
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ | |||
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC)) | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F401xx) | |||
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ | |||
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ | |||
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ | |||
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ | |||
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ | |||
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ | |||
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ | |||
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ | |||
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ | |||
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \ | |||
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ | |||
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4)) | |||
#endif /* STM32F401xx */ | |||
#if defined (STM32F411xE) | |||
#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14)) | |||
#endif /* STM32F411xE */ | |||
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ | |||
((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ | |||
((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ | |||
((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ | |||
((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ | |||
((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ | |||
((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ | |||
((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ | |||
((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ | |||
((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ | |||
((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ | |||
((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ | |||
((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ | |||
((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ | |||
((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ | |||
((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ | |||
((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \ | |||
((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \ | |||
((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \ | |||
((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \ | |||
((AF) == GPIO_AF_LTDC)) | |||
#endif /* STM32F427_437xx || STM32F429_439xx */ | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup GPIO_Legacy | |||
* @{ | |||
*/ | |||
#define GPIO_Mode_AIN GPIO_Mode_AN | |||
#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS | |||
#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS | |||
#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
/* Function used to set the GPIO configuration to the default reset state ****/ | |||
void GPIO_DeInit(GPIO_TypeDef* GPIOx); | |||
/* Initialization and Configuration functions *********************************/ | |||
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); | |||
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); | |||
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
/* GPIO Read and Write functions **********************************************/ | |||
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); | |||
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); | |||
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); | |||
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); | |||
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); | |||
/* GPIO Alternate functions configuration function ****************************/ | |||
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /*__STM32F4xx_GPIO_H */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,630 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_rcc.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains all the functions prototypes for the RCC firmware library. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_RCC_H | |||
#define __STM32F4xx_RCC_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup RCC | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
typedef struct | |||
{ | |||
uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency expressed in Hz */ | |||
uint32_t HCLK_Frequency; /*!< HCLK clock frequency expressed in Hz */ | |||
uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency expressed in Hz */ | |||
uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency expressed in Hz */ | |||
}RCC_ClocksTypeDef; | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup RCC_Exported_Constants | |||
* @{ | |||
*/ | |||
/** @defgroup RCC_HSE_configuration | |||
* @{ | |||
*/ | |||
#define RCC_HSE_OFF ((uint8_t)0x00) | |||
#define RCC_HSE_ON ((uint8_t)0x01) | |||
#define RCC_HSE_Bypass ((uint8_t)0x05) | |||
#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ | |||
((HSE) == RCC_HSE_Bypass)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_LSE_Dual_Mode_Selection | |||
* @{ | |||
*/ | |||
#define RCC_LSE_LOWPOWER_MODE ((uint8_t)0x00) | |||
#define RCC_LSE_HIGHDRIVE_MODE ((uint8_t)0x01) | |||
#define IS_RCC_LSE_MODE(MODE) (((MODE) == RCC_LSE_LOWPOWER_MODE) || \ | |||
((MODE) == RCC_LSE_HIGHDRIVE_MODE)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_PLL_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_PLLSource_HSI ((uint32_t)0x00000000) | |||
#define RCC_PLLSource_HSE ((uint32_t)0x00400000) | |||
#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \ | |||
((SOURCE) == RCC_PLLSource_HSE)) | |||
#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63) | |||
#define IS_RCC_PLLN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) | |||
#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8)) | |||
#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15)) | |||
#define IS_RCC_PLLI2SN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) | |||
#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) | |||
#define IS_RCC_PLLI2SM_VALUE(VALUE) ((VALUE) <= 63) | |||
#define IS_RCC_PLLI2SQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15)) | |||
#define IS_RCC_PLLSAIN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) | |||
#define IS_RCC_PLLSAIQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15)) | |||
#define IS_RCC_PLLSAIR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) | |||
#define IS_RCC_PLLSAI_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32)) | |||
#define IS_RCC_PLLI2S_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32)) | |||
#define RCC_PLLSAIDivR_Div2 ((uint32_t)0x00000000) | |||
#define RCC_PLLSAIDivR_Div4 ((uint32_t)0x00010000) | |||
#define RCC_PLLSAIDivR_Div8 ((uint32_t)0x00020000) | |||
#define RCC_PLLSAIDivR_Div16 ((uint32_t)0x00030000) | |||
#define IS_RCC_PLLSAI_DIVR_VALUE(VALUE) (((VALUE) == RCC_PLLSAIDivR_Div2) ||\ | |||
((VALUE) == RCC_PLLSAIDivR_Div4) ||\ | |||
((VALUE) == RCC_PLLSAIDivR_Div8) ||\ | |||
((VALUE) == RCC_PLLSAIDivR_Div16)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_System_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000) | |||
#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001) | |||
#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002) | |||
#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \ | |||
((SOURCE) == RCC_SYSCLKSource_HSE) || \ | |||
((SOURCE) == RCC_SYSCLKSource_PLLCLK)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_AHB_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000) | |||
#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080) | |||
#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090) | |||
#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0) | |||
#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0) | |||
#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0) | |||
#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0) | |||
#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0) | |||
#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0) | |||
#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \ | |||
((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \ | |||
((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \ | |||
((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \ | |||
((HCLK) == RCC_SYSCLK_Div512)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_APB1_APB2_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_HCLK_Div1 ((uint32_t)0x00000000) | |||
#define RCC_HCLK_Div2 ((uint32_t)0x00001000) | |||
#define RCC_HCLK_Div4 ((uint32_t)0x00001400) | |||
#define RCC_HCLK_Div8 ((uint32_t)0x00001800) | |||
#define RCC_HCLK_Div16 ((uint32_t)0x00001C00) | |||
#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \ | |||
((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \ | |||
((PCLK) == RCC_HCLK_Div16)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_Interrupt_Source | |||
* @{ | |||
*/ | |||
#define RCC_IT_LSIRDY ((uint8_t)0x01) | |||
#define RCC_IT_LSERDY ((uint8_t)0x02) | |||
#define RCC_IT_HSIRDY ((uint8_t)0x04) | |||
#define RCC_IT_HSERDY ((uint8_t)0x08) | |||
#define RCC_IT_PLLRDY ((uint8_t)0x10) | |||
#define RCC_IT_PLLI2SRDY ((uint8_t)0x20) | |||
#define RCC_IT_PLLSAIRDY ((uint8_t)0x40) | |||
#define RCC_IT_CSS ((uint8_t)0x80) | |||
#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0x80) == 0x00) && ((IT) != 0x00)) | |||
#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \ | |||
((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \ | |||
((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \ | |||
((IT) == RCC_IT_PLLSAIRDY) || ((IT) == RCC_IT_PLLI2SRDY)) | |||
#define IS_RCC_CLEAR_IT(IT)((IT) != 0x00) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_LSE_Configuration | |||
* @{ | |||
*/ | |||
#define RCC_LSE_OFF ((uint8_t)0x00) | |||
#define RCC_LSE_ON ((uint8_t)0x01) | |||
#define RCC_LSE_Bypass ((uint8_t)0x04) | |||
#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ | |||
((LSE) == RCC_LSE_Bypass)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_RTC_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100) | |||
#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200) | |||
#define RCC_RTCCLKSource_HSE_Div2 ((uint32_t)0x00020300) | |||
#define RCC_RTCCLKSource_HSE_Div3 ((uint32_t)0x00030300) | |||
#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)0x00040300) | |||
#define RCC_RTCCLKSource_HSE_Div5 ((uint32_t)0x00050300) | |||
#define RCC_RTCCLKSource_HSE_Div6 ((uint32_t)0x00060300) | |||
#define RCC_RTCCLKSource_HSE_Div7 ((uint32_t)0x00070300) | |||
#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)0x00080300) | |||
#define RCC_RTCCLKSource_HSE_Div9 ((uint32_t)0x00090300) | |||
#define RCC_RTCCLKSource_HSE_Div10 ((uint32_t)0x000A0300) | |||
#define RCC_RTCCLKSource_HSE_Div11 ((uint32_t)0x000B0300) | |||
#define RCC_RTCCLKSource_HSE_Div12 ((uint32_t)0x000C0300) | |||
#define RCC_RTCCLKSource_HSE_Div13 ((uint32_t)0x000D0300) | |||
#define RCC_RTCCLKSource_HSE_Div14 ((uint32_t)0x000E0300) | |||
#define RCC_RTCCLKSource_HSE_Div15 ((uint32_t)0x000F0300) | |||
#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)0x00100300) | |||
#define RCC_RTCCLKSource_HSE_Div17 ((uint32_t)0x00110300) | |||
#define RCC_RTCCLKSource_HSE_Div18 ((uint32_t)0x00120300) | |||
#define RCC_RTCCLKSource_HSE_Div19 ((uint32_t)0x00130300) | |||
#define RCC_RTCCLKSource_HSE_Div20 ((uint32_t)0x00140300) | |||
#define RCC_RTCCLKSource_HSE_Div21 ((uint32_t)0x00150300) | |||
#define RCC_RTCCLKSource_HSE_Div22 ((uint32_t)0x00160300) | |||
#define RCC_RTCCLKSource_HSE_Div23 ((uint32_t)0x00170300) | |||
#define RCC_RTCCLKSource_HSE_Div24 ((uint32_t)0x00180300) | |||
#define RCC_RTCCLKSource_HSE_Div25 ((uint32_t)0x00190300) | |||
#define RCC_RTCCLKSource_HSE_Div26 ((uint32_t)0x001A0300) | |||
#define RCC_RTCCLKSource_HSE_Div27 ((uint32_t)0x001B0300) | |||
#define RCC_RTCCLKSource_HSE_Div28 ((uint32_t)0x001C0300) | |||
#define RCC_RTCCLKSource_HSE_Div29 ((uint32_t)0x001D0300) | |||
#define RCC_RTCCLKSource_HSE_Div30 ((uint32_t)0x001E0300) | |||
#define RCC_RTCCLKSource_HSE_Div31 ((uint32_t)0x001F0300) | |||
#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \ | |||
((SOURCE) == RCC_RTCCLKSource_LSI) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div3) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div5) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div6) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div7) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div9) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div10) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div11) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div12) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div13) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div14) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div15) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div16) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div17) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div18) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div19) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div20) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div21) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div22) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div23) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div24) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div25) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div26) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div27) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div28) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div29) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div30) || \ | |||
((SOURCE) == RCC_RTCCLKSource_HSE_Div31)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_I2S_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_I2S2CLKSource_PLLI2S ((uint8_t)0x00) | |||
#define RCC_I2S2CLKSource_Ext ((uint8_t)0x01) | |||
#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_PLLI2S) || ((SOURCE) == RCC_I2S2CLKSource_Ext)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_SAI_BlockA_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_SAIACLKSource_PLLSAI ((uint32_t)0x00000000) | |||
#define RCC_SAIACLKSource_PLLI2S ((uint32_t)0x00100000) | |||
#define RCC_SAIACLKSource_Ext ((uint32_t)0x00200000) | |||
#define IS_RCC_SAIACLK_SOURCE(SOURCE) (((SOURCE) == RCC_SAIACLKSource_PLLI2S) ||\ | |||
((SOURCE) == RCC_SAIACLKSource_PLLSAI) ||\ | |||
((SOURCE) == RCC_SAIACLKSource_Ext)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_SAI_BlockB_Clock_Source | |||
* @{ | |||
*/ | |||
#define RCC_SAIBCLKSource_PLLSAI ((uint32_t)0x00000000) | |||
#define RCC_SAIBCLKSource_PLLI2S ((uint32_t)0x00400000) | |||
#define RCC_SAIBCLKSource_Ext ((uint32_t)0x00800000) | |||
#define IS_RCC_SAIBCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SAIBCLKSource_PLLI2S) ||\ | |||
((SOURCE) == RCC_SAIBCLKSource_PLLSAI) ||\ | |||
((SOURCE) == RCC_SAIBCLKSource_Ext)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_TIM_PRescaler_Selection | |||
* @{ | |||
*/ | |||
#define RCC_TIMPrescDesactivated ((uint8_t)0x00) | |||
#define RCC_TIMPrescActivated ((uint8_t)0x01) | |||
#define IS_RCC_TIMCLK_PRESCALER(VALUE) (((VALUE) == RCC_TIMPrescDesactivated) || ((VALUE) == RCC_TIMPrescActivated)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_AHB1_Peripherals | |||
* @{ | |||
*/ | |||
#define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001) | |||
#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002) | |||
#define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004) | |||
#define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008) | |||
#define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010) | |||
#define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020) | |||
#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040) | |||
#define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080) | |||
#define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100) | |||
#define RCC_AHB1Periph_GPIOJ ((uint32_t)0x00000200) | |||
#define RCC_AHB1Periph_GPIOK ((uint32_t)0x00000400) | |||
#define RCC_AHB1Periph_CRC ((uint32_t)0x00001000) | |||
#define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000) | |||
#define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000) | |||
#define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000) | |||
#define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000) | |||
#define RCC_AHB1Periph_SRAM3 ((uint32_t)0x00080000) | |||
#define RCC_AHB1Periph_CCMDATARAMEN ((uint32_t)0x00100000) | |||
#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000) | |||
#define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000) | |||
#define RCC_AHB1Periph_DMA2D ((uint32_t)0x00800000) | |||
#define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000) | |||
#define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000) | |||
#define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000) | |||
#define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000) | |||
#define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000) | |||
#define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000) | |||
#define IS_RCC_AHB1_CLOCK_PERIPH(PERIPH) ((((PERIPH) & 0x810BE800) == 0x00) && ((PERIPH) != 0x00)) | |||
#define IS_RCC_AHB1_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xDD1FE800) == 0x00) && ((PERIPH) != 0x00)) | |||
#define IS_RCC_AHB1_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0x81106800) == 0x00) && ((PERIPH) != 0x00)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_AHB2_Peripherals | |||
* @{ | |||
*/ | |||
#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001) | |||
#define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010) | |||
#define RCC_AHB2Periph_HASH ((uint32_t)0x00000020) | |||
#define RCC_AHB2Periph_RNG ((uint32_t)0x00000040) | |||
#define RCC_AHB2Periph_OTG_FS ((uint32_t)0x00000080) | |||
#define IS_RCC_AHB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFF0E) == 0x00) && ((PERIPH) != 0x00)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_AHB3_Peripherals | |||
* @{ | |||
*/ | |||
#if defined (STM32F40_41xxx) | |||
#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001) | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
#define RCC_AHB3Periph_FMC ((uint32_t)0x00000001) | |||
#endif /* STM32F427_437xx || STM32F429_439xx */ | |||
#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_APB1_Peripherals | |||
* @{ | |||
*/ | |||
#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) | |||
#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002) | |||
#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004) | |||
#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008) | |||
#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010) | |||
#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020) | |||
#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040) | |||
#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080) | |||
#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100) | |||
#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800) | |||
#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000) | |||
#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000) | |||
#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000) | |||
#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000) | |||
#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000) | |||
#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000) | |||
#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000) | |||
#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000) | |||
#define RCC_APB1Periph_I2C3 ((uint32_t)0x00800000) | |||
#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000) | |||
#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000) | |||
#define RCC_APB1Periph_PWR ((uint32_t)0x10000000) | |||
#define RCC_APB1Periph_DAC ((uint32_t)0x20000000) | |||
#define RCC_APB1Periph_UART7 ((uint32_t)0x40000000) | |||
#define RCC_APB1Periph_UART8 ((uint32_t)0x80000000) | |||
#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0x09013600) == 0x00) && ((PERIPH) != 0x00)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_APB2_Peripherals | |||
* @{ | |||
*/ | |||
#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000001) | |||
#define RCC_APB2Periph_TIM8 ((uint32_t)0x00000002) | |||
#define RCC_APB2Periph_USART1 ((uint32_t)0x00000010) | |||
#define RCC_APB2Periph_USART6 ((uint32_t)0x00000020) | |||
#define RCC_APB2Periph_ADC ((uint32_t)0x00000100) | |||
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100) | |||
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200) | |||
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400) | |||
#define RCC_APB2Periph_SDIO ((uint32_t)0x00000800) | |||
#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000) | |||
#define RCC_APB2Periph_SPI4 ((uint32_t)0x00002000) | |||
#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000) | |||
#define RCC_APB2Periph_TIM9 ((uint32_t)0x00010000) | |||
#define RCC_APB2Periph_TIM10 ((uint32_t)0x00020000) | |||
#define RCC_APB2Periph_TIM11 ((uint32_t)0x00040000) | |||
#define RCC_APB2Periph_SPI5 ((uint32_t)0x00100000) | |||
#define RCC_APB2Periph_SPI6 ((uint32_t)0x00200000) | |||
#define RCC_APB2Periph_SAI1 ((uint32_t)0x00400000) | |||
#define RCC_APB2Periph_LTDC ((uint32_t)0x04000000) | |||
#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFB8880CC) == 0x00) && ((PERIPH) != 0x00)) | |||
#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xFB8886CC) == 0x00) && ((PERIPH) != 0x00)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_MCO1_Clock_Source_Prescaler | |||
* @{ | |||
*/ | |||
#define RCC_MCO1Source_HSI ((uint32_t)0x00000000) | |||
#define RCC_MCO1Source_LSE ((uint32_t)0x00200000) | |||
#define RCC_MCO1Source_HSE ((uint32_t)0x00400000) | |||
#define RCC_MCO1Source_PLLCLK ((uint32_t)0x00600000) | |||
#define RCC_MCO1Div_1 ((uint32_t)0x00000000) | |||
#define RCC_MCO1Div_2 ((uint32_t)0x04000000) | |||
#define RCC_MCO1Div_3 ((uint32_t)0x05000000) | |||
#define RCC_MCO1Div_4 ((uint32_t)0x06000000) | |||
#define RCC_MCO1Div_5 ((uint32_t)0x07000000) | |||
#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1Source_HSI) || ((SOURCE) == RCC_MCO1Source_LSE) || \ | |||
((SOURCE) == RCC_MCO1Source_HSE) || ((SOURCE) == RCC_MCO1Source_PLLCLK)) | |||
#define IS_RCC_MCO1DIV(DIV) (((DIV) == RCC_MCO1Div_1) || ((DIV) == RCC_MCO1Div_2) || \ | |||
((DIV) == RCC_MCO1Div_3) || ((DIV) == RCC_MCO1Div_4) || \ | |||
((DIV) == RCC_MCO1Div_5)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_MCO2_Clock_Source_Prescaler | |||
* @{ | |||
*/ | |||
#define RCC_MCO2Source_SYSCLK ((uint32_t)0x00000000) | |||
#define RCC_MCO2Source_PLLI2SCLK ((uint32_t)0x40000000) | |||
#define RCC_MCO2Source_HSE ((uint32_t)0x80000000) | |||
#define RCC_MCO2Source_PLLCLK ((uint32_t)0xC0000000) | |||
#define RCC_MCO2Div_1 ((uint32_t)0x00000000) | |||
#define RCC_MCO2Div_2 ((uint32_t)0x20000000) | |||
#define RCC_MCO2Div_3 ((uint32_t)0x28000000) | |||
#define RCC_MCO2Div_4 ((uint32_t)0x30000000) | |||
#define RCC_MCO2Div_5 ((uint32_t)0x38000000) | |||
#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2Source_SYSCLK) || ((SOURCE) == RCC_MCO2Source_PLLI2SCLK)|| \ | |||
((SOURCE) == RCC_MCO2Source_HSE) || ((SOURCE) == RCC_MCO2Source_PLLCLK)) | |||
#define IS_RCC_MCO2DIV(DIV) (((DIV) == RCC_MCO2Div_1) || ((DIV) == RCC_MCO2Div_2) || \ | |||
((DIV) == RCC_MCO2Div_3) || ((DIV) == RCC_MCO2Div_4) || \ | |||
((DIV) == RCC_MCO2Div_5)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup RCC_Flag | |||
* @{ | |||
*/ | |||
#define RCC_FLAG_HSIRDY ((uint8_t)0x21) | |||
#define RCC_FLAG_HSERDY ((uint8_t)0x31) | |||
#define RCC_FLAG_PLLRDY ((uint8_t)0x39) | |||
#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B) | |||
#define RCC_FLAG_PLLSAIRDY ((uint8_t)0x3D) | |||
#define RCC_FLAG_LSERDY ((uint8_t)0x41) | |||
#define RCC_FLAG_LSIRDY ((uint8_t)0x61) | |||
#define RCC_FLAG_BORRST ((uint8_t)0x79) | |||
#define RCC_FLAG_PINRST ((uint8_t)0x7A) | |||
#define RCC_FLAG_PORRST ((uint8_t)0x7B) | |||
#define RCC_FLAG_SFTRST ((uint8_t)0x7C) | |||
#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) | |||
#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) | |||
#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) | |||
#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \ | |||
((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \ | |||
((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_BORRST) || \ | |||
((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \ | |||
((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \ | |||
((FLAG) == RCC_FLAG_WWDGRST) || ((FLAG) == RCC_FLAG_LPWRRST)|| \ | |||
((FLAG) == RCC_FLAG_PLLI2SRDY)|| ((FLAG) == RCC_FLAG_PLLSAIRDY)) | |||
#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
/* Function used to set the RCC clock configuration to the default reset state */ | |||
void RCC_DeInit(void); | |||
/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/ | |||
void RCC_HSEConfig(uint8_t RCC_HSE); | |||
ErrorStatus RCC_WaitForHSEStartUp(void); | |||
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue); | |||
void RCC_HSICmd(FunctionalState NewState); | |||
void RCC_LSEConfig(uint8_t RCC_LSE); | |||
void RCC_LSICmd(FunctionalState NewState); | |||
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ); | |||
void RCC_PLLCmd(FunctionalState NewState); | |||
#if defined (STM32F40_41xxx) || defined (STM32F401xx) | |||
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR); | |||
#elif defined (STM32F411xE) | |||
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR, uint32_t PLLI2SM); | |||
#elif defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SQ, uint32_t PLLI2SR); | |||
#else | |||
#endif /* STM32F40_41xxx || STM32F401xx */ | |||
void RCC_PLLI2SCmd(FunctionalState NewState); | |||
void RCC_PLLSAIConfig(uint32_t PLLSAIN, uint32_t PLLSAIQ, uint32_t PLLSAIR); | |||
void RCC_PLLSAICmd(FunctionalState NewState); | |||
void RCC_ClockSecuritySystemCmd(FunctionalState NewState); | |||
void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div); | |||
void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div); | |||
/* System, AHB and APB busses clocks configuration functions ******************/ | |||
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); | |||
uint8_t RCC_GetSYSCLKSource(void); | |||
void RCC_HCLKConfig(uint32_t RCC_SYSCLK); | |||
void RCC_PCLK1Config(uint32_t RCC_HCLK); | |||
void RCC_PCLK2Config(uint32_t RCC_HCLK); | |||
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); | |||
/* Peripheral clocks configuration functions **********************************/ | |||
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); | |||
void RCC_RTCCLKCmd(FunctionalState NewState); | |||
void RCC_BackupResetCmd(FunctionalState NewState); | |||
void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource); | |||
void RCC_SAIPLLI2SClkDivConfig(uint32_t RCC_PLLI2SDivQ); | |||
void RCC_SAIPLLSAIClkDivConfig(uint32_t RCC_PLLSAIDivQ); | |||
void RCC_SAIBlockACLKConfig(uint32_t RCC_SAIBlockACLKSource); | |||
void RCC_SAIBlockBCLKConfig(uint32_t RCC_SAIBlockBCLKSource); | |||
void RCC_LTDCCLKDivConfig(uint32_t RCC_PLLSAIDivR); | |||
void RCC_TIMCLKPresConfig(uint32_t RCC_TIMCLKPrescaler); | |||
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); | |||
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); | |||
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); | |||
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); | |||
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); | |||
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); | |||
void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); | |||
void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); | |||
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); | |||
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); | |||
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); | |||
void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); | |||
void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); | |||
void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); | |||
void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); | |||
void RCC_LSEModeConfig(uint8_t Mode); | |||
/* Interrupts and flags management functions **********************************/ | |||
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState); | |||
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); | |||
void RCC_ClearFlag(void); | |||
ITStatus RCC_GetITStatus(uint8_t RCC_IT); | |||
void RCC_ClearITPendingBit(uint8_t RCC_IT); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* __STM32F4xx_RCC_H */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,210 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_syscfg.h | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file contains all the functions prototypes for the SYSCFG firmware | |||
* library. | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Define to prevent recursive inclusion -------------------------------------*/ | |||
#ifndef __STM32F4xx_SYSCFG_H | |||
#define __STM32F4xx_SYSCFG_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @addtogroup SYSCFG | |||
* @{ | |||
*/ | |||
/* Exported types ------------------------------------------------------------*/ | |||
/* Exported constants --------------------------------------------------------*/ | |||
/** @defgroup SYSCFG_Exported_Constants | |||
* @{ | |||
*/ | |||
/** @defgroup SYSCFG_EXTI_Port_Sources | |||
* @{ | |||
*/ | |||
#define EXTI_PortSourceGPIOA ((uint8_t)0x00) | |||
#define EXTI_PortSourceGPIOB ((uint8_t)0x01) | |||
#define EXTI_PortSourceGPIOC ((uint8_t)0x02) | |||
#define EXTI_PortSourceGPIOD ((uint8_t)0x03) | |||
#define EXTI_PortSourceGPIOE ((uint8_t)0x04) | |||
#define EXTI_PortSourceGPIOF ((uint8_t)0x05) | |||
#define EXTI_PortSourceGPIOG ((uint8_t)0x06) | |||
#define EXTI_PortSourceGPIOH ((uint8_t)0x07) | |||
#define EXTI_PortSourceGPIOI ((uint8_t)0x08) | |||
#define EXTI_PortSourceGPIOJ ((uint8_t)0x09) | |||
#define EXTI_PortSourceGPIOK ((uint8_t)0x0A) | |||
#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOB) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOC) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOD) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOE) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOF) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOG) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOH) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOI) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOJ) || \ | |||
((PORTSOURCE) == EXTI_PortSourceGPIOK)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup SYSCFG_EXTI_Pin_Sources | |||
* @{ | |||
*/ | |||
#define EXTI_PinSource0 ((uint8_t)0x00) | |||
#define EXTI_PinSource1 ((uint8_t)0x01) | |||
#define EXTI_PinSource2 ((uint8_t)0x02) | |||
#define EXTI_PinSource3 ((uint8_t)0x03) | |||
#define EXTI_PinSource4 ((uint8_t)0x04) | |||
#define EXTI_PinSource5 ((uint8_t)0x05) | |||
#define EXTI_PinSource6 ((uint8_t)0x06) | |||
#define EXTI_PinSource7 ((uint8_t)0x07) | |||
#define EXTI_PinSource8 ((uint8_t)0x08) | |||
#define EXTI_PinSource9 ((uint8_t)0x09) | |||
#define EXTI_PinSource10 ((uint8_t)0x0A) | |||
#define EXTI_PinSource11 ((uint8_t)0x0B) | |||
#define EXTI_PinSource12 ((uint8_t)0x0C) | |||
#define EXTI_PinSource13 ((uint8_t)0x0D) | |||
#define EXTI_PinSource14 ((uint8_t)0x0E) | |||
#define EXTI_PinSource15 ((uint8_t)0x0F) | |||
#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \ | |||
((PINSOURCE) == EXTI_PinSource1) || \ | |||
((PINSOURCE) == EXTI_PinSource2) || \ | |||
((PINSOURCE) == EXTI_PinSource3) || \ | |||
((PINSOURCE) == EXTI_PinSource4) || \ | |||
((PINSOURCE) == EXTI_PinSource5) || \ | |||
((PINSOURCE) == EXTI_PinSource6) || \ | |||
((PINSOURCE) == EXTI_PinSource7) || \ | |||
((PINSOURCE) == EXTI_PinSource8) || \ | |||
((PINSOURCE) == EXTI_PinSource9) || \ | |||
((PINSOURCE) == EXTI_PinSource10) || \ | |||
((PINSOURCE) == EXTI_PinSource11) || \ | |||
((PINSOURCE) == EXTI_PinSource12) || \ | |||
((PINSOURCE) == EXTI_PinSource13) || \ | |||
((PINSOURCE) == EXTI_PinSource14) || \ | |||
((PINSOURCE) == EXTI_PinSource15)) | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup SYSCFG_Memory_Remap_Config | |||
* @{ | |||
*/ | |||
#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00) | |||
#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01) | |||
#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03) | |||
#define SYSCFG_MemoryRemap_SDRAM ((uint8_t)0x04) | |||
#if defined (STM32F40_41xxx) | |||
#define SYSCFG_MemoryRemap_FSMC ((uint8_t)0x02) | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
#define SYSCFG_MemoryRemap_FMC ((uint8_t)0x02) | |||
#endif /* STM32F427_437xx || STM32F429_439xx */ | |||
#if defined (STM32F40_41xxx) | |||
#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SRAM) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_FSMC)) | |||
#endif /* STM32F40_41xxx */ | |||
#if defined (STM32F401xx) || defined (STM32F411xE) | |||
#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SRAM)) | |||
#endif /* STM32F401xx || STM32F411xE */ | |||
#if defined (STM32F427_437xx) || defined (STM32F429_439xx) | |||
#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SRAM) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_SDRAM) || \ | |||
((REMAP) == SYSCFG_MemoryRemap_FMC)) | |||
#endif /* STM32F427_437xx || STM32F429_439xx */ | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup SYSCFG_ETHERNET_Media_Interface | |||
* @{ | |||
*/ | |||
#define SYSCFG_ETH_MediaInterface_MII ((uint32_t)0x00000000) | |||
#define SYSCFG_ETH_MediaInterface_RMII ((uint32_t)0x00000001) | |||
#define IS_SYSCFG_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == SYSCFG_ETH_MediaInterface_MII) || \ | |||
((INTERFACE) == SYSCFG_ETH_MediaInterface_RMII)) | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/* Exported macro ------------------------------------------------------------*/ | |||
/* Exported functions --------------------------------------------------------*/ | |||
void SYSCFG_DeInit(void); | |||
void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap); | |||
void SYSCFG_MemorySwappingBank(FunctionalState NewState); | |||
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); | |||
void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface); | |||
void SYSCFG_CompensationCellCmd(FunctionalState NewState); | |||
FlagStatus SYSCFG_GetCompensationCellStatus(void); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /*__STM32F4xx_SYSCFG_H */ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,249 @@ | |||
/** | |||
****************************************************************************** | |||
* @file misc.c | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file provides all the miscellaneous firmware functions (add-on | |||
* to CMSIS functions). | |||
* | |||
* @verbatim | |||
* | |||
* =================================================================== | |||
* How to configure Interrupts using driver | |||
* =================================================================== | |||
* | |||
* This section provide functions allowing to configure the NVIC interrupts (IRQ). | |||
* The Cortex-M4 exceptions are managed by CMSIS functions. | |||
* | |||
* 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig() | |||
* function according to the following table. | |||
* The table below gives the allowed values of the pre-emption priority and subpriority according | |||
* to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function | |||
* ========================================================================================================================== | |||
* NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description | |||
* ========================================================================================================================== | |||
* NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority | |||
* | | | 4 bits for subpriority | |||
* -------------------------------------------------------------------------------------------------------------------------- | |||
* NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority | |||
* | | | 3 bits for subpriority | |||
* -------------------------------------------------------------------------------------------------------------------------- | |||
* NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority | |||
* | | | 2 bits for subpriority | |||
* -------------------------------------------------------------------------------------------------------------------------- | |||
* NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority | |||
* | | | 1 bits for subpriority | |||
* -------------------------------------------------------------------------------------------------------------------------- | |||
* NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority | |||
* | | | 0 bits for subpriority | |||
* ========================================================================================================================== | |||
* | |||
* 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init() | |||
* | |||
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. | |||
* The pending IRQ priority will be managed only by the subpriority. | |||
* | |||
* @note IRQ priority order (sorted by highest to lowest priority): | |||
* - Lowest pre-emption priority | |||
* - Lowest subpriority | |||
* - Lowest hardware priority (IRQ number) | |||
* | |||
* @endverbatim | |||
* | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "misc.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @defgroup MISC | |||
* @brief MISC driver modules | |||
* @{ | |||
*/ | |||
/* Private typedef -----------------------------------------------------------*/ | |||
/* Private define ------------------------------------------------------------*/ | |||
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) | |||
/* Private macro -------------------------------------------------------------*/ | |||
/* Private variables ---------------------------------------------------------*/ | |||
/* Private function prototypes -----------------------------------------------*/ | |||
/* Private functions ---------------------------------------------------------*/ | |||
/** @defgroup MISC_Private_Functions | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Configures the priority grouping: pre-emption priority and subpriority. | |||
* @param NVIC_PriorityGroup: specifies the priority grouping bits length. | |||
* This parameter can be one of the following values: | |||
* @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority | |||
* 4 bits for subpriority | |||
* @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority | |||
* 3 bits for subpriority | |||
* @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority | |||
* 2 bits for subpriority | |||
* @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority | |||
* 1 bits for subpriority | |||
* @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority | |||
* 0 bits for subpriority | |||
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. | |||
* The pending IRQ priority will be managed only by the subpriority. | |||
* @retval None | |||
*/ | |||
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); | |||
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ | |||
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; | |||
} | |||
/** | |||
* @brief Initializes the NVIC peripheral according to the specified | |||
* parameters in the NVIC_InitStruct. | |||
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() | |||
* function should be called before. | |||
* @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains | |||
* the configuration information for the specified NVIC peripheral. | |||
* @retval None | |||
*/ | |||
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) | |||
{ | |||
uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F; | |||
/* Check the parameters */ | |||
assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); | |||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority)); | |||
assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority)); | |||
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) | |||
{ | |||
/* Compute the Corresponding IRQ Priority --------------------------------*/ | |||
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; | |||
tmppre = (0x4 - tmppriority); | |||
tmpsub = tmpsub >> tmppriority; | |||
tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; | |||
tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); | |||
tmppriority = tmppriority << 0x04; | |||
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; | |||
/* Enable the Selected IRQ Channels --------------------------------------*/ | |||
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = | |||
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); | |||
} | |||
else | |||
{ | |||
/* Disable the Selected IRQ Channels -------------------------------------*/ | |||
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = | |||
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); | |||
} | |||
} | |||
/** | |||
* @brief Sets the vector table location and Offset. | |||
* @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory. | |||
* This parameter can be one of the following values: | |||
* @arg NVIC_VectTab_RAM: Vector Table in internal SRAM. | |||
* @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH. | |||
* @param Offset: Vector Table base offset field. This value must be a multiple of 0x200. | |||
* @retval None | |||
*/ | |||
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab)); | |||
assert_param(IS_NVIC_OFFSET(Offset)); | |||
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); | |||
} | |||
/** | |||
* @brief Selects the condition for the system to enter low power mode. | |||
* @param LowPowerMode: Specifies the new mode for the system to enter low power mode. | |||
* This parameter can be one of the following values: | |||
* @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend. | |||
* @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request. | |||
* @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit. | |||
* @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE. | |||
* @retval None | |||
*/ | |||
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_NVIC_LP(LowPowerMode)); | |||
assert_param(IS_FUNCTIONAL_STATE(NewState)); | |||
if (NewState != DISABLE) | |||
{ | |||
SCB->SCR |= LowPowerMode; | |||
} | |||
else | |||
{ | |||
SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode); | |||
} | |||
} | |||
/** | |||
* @brief Configures the SysTick clock source. | |||
* @param SysTick_CLKSource: specifies the SysTick clock source. | |||
* This parameter can be one of the following values: | |||
* @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. | |||
* @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. | |||
* @retval None | |||
*/ | |||
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); | |||
if (SysTick_CLKSource == SysTick_CLKSource_HCLK) | |||
{ | |||
SysTick->CTRL |= SysTick_CLKSource_HCLK; | |||
} | |||
else | |||
{ | |||
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; | |||
} | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,311 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_exti.c | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file provides firmware functions to manage the following | |||
* functionalities of the EXTI peripheral: | |||
* + Initialization and Configuration | |||
* + Interrupts and flags management | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### EXTI features ##### | |||
=============================================================================== | |||
[..] External interrupt/event lines are mapped as following: | |||
(#) All available GPIO pins are connected to the 16 external | |||
interrupt/event lines from EXTI0 to EXTI15. | |||
(#) EXTI line 16 is connected to the PVD Output | |||
(#) EXTI line 17 is connected to the RTC Alarm event | |||
(#) EXTI line 18 is connected to the USB OTG FS Wakeup from suspend event | |||
(#) EXTI line 19 is connected to the Ethernet Wakeup event | |||
(#) EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event | |||
(#) EXTI line 21 is connected to the RTC Tamper and Time Stamp events | |||
(#) EXTI line 22 is connected to the RTC Wakeup event | |||
##### How to use this driver ##### | |||
=============================================================================== | |||
[..] In order to use an I/O pin as an external interrupt source, follow steps | |||
below: | |||
(#) Configure the I/O in input mode using GPIO_Init() | |||
(#) Select the input source pin for the EXTI line using SYSCFG_EXTILineConfig() | |||
(#) Select the mode(interrupt, event) and configure the trigger | |||
selection (Rising, falling or both) using EXTI_Init() | |||
(#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init() | |||
[..] | |||
(@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx | |||
registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); | |||
@endverbatim | |||
* | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx_exti.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @defgroup EXTI | |||
* @brief EXTI driver modules | |||
* @{ | |||
*/ | |||
/* Private typedef -----------------------------------------------------------*/ | |||
/* Private define ------------------------------------------------------------*/ | |||
#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */ | |||
/* Private macro -------------------------------------------------------------*/ | |||
/* Private variables ---------------------------------------------------------*/ | |||
/* Private function prototypes -----------------------------------------------*/ | |||
/* Private functions ---------------------------------------------------------*/ | |||
/** @defgroup EXTI_Private_Functions | |||
* @{ | |||
*/ | |||
/** @defgroup EXTI_Group1 Initialization and Configuration functions | |||
* @brief Initialization and Configuration functions | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### Initialization and Configuration functions ##### | |||
=============================================================================== | |||
@endverbatim | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Deinitializes the EXTI peripheral registers to their default reset values. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void EXTI_DeInit(void) | |||
{ | |||
EXTI->IMR = 0x00000000; | |||
EXTI->EMR = 0x00000000; | |||
EXTI->RTSR = 0x00000000; | |||
EXTI->FTSR = 0x00000000; | |||
EXTI->PR = 0x007FFFFF; | |||
} | |||
/** | |||
* @brief Initializes the EXTI peripheral according to the specified | |||
* parameters in the EXTI_InitStruct. | |||
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure | |||
* that contains the configuration information for the EXTI peripheral. | |||
* @retval None | |||
*/ | |||
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) | |||
{ | |||
uint32_t tmp = 0; | |||
/* Check the parameters */ | |||
assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode)); | |||
assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger)); | |||
assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line)); | |||
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd)); | |||
tmp = (uint32_t)EXTI_BASE; | |||
if (EXTI_InitStruct->EXTI_LineCmd != DISABLE) | |||
{ | |||
/* Clear EXTI line configuration */ | |||
EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line; | |||
EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line; | |||
tmp += EXTI_InitStruct->EXTI_Mode; | |||
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; | |||
/* Clear Rising Falling edge configuration */ | |||
EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line; | |||
EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line; | |||
/* Select the trigger for the selected external interrupts */ | |||
if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) | |||
{ | |||
/* Rising Falling edge */ | |||
EXTI->RTSR |= EXTI_InitStruct->EXTI_Line; | |||
EXTI->FTSR |= EXTI_InitStruct->EXTI_Line; | |||
} | |||
else | |||
{ | |||
tmp = (uint32_t)EXTI_BASE; | |||
tmp += EXTI_InitStruct->EXTI_Trigger; | |||
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line; | |||
} | |||
} | |||
else | |||
{ | |||
tmp += EXTI_InitStruct->EXTI_Mode; | |||
/* Disable the selected external lines */ | |||
*(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line; | |||
} | |||
} | |||
/** | |||
* @brief Fills each EXTI_InitStruct member with its reset value. | |||
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will | |||
* be initialized. | |||
* @retval None | |||
*/ | |||
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct) | |||
{ | |||
EXTI_InitStruct->EXTI_Line = EXTI_LINENONE; | |||
EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt; | |||
EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling; | |||
EXTI_InitStruct->EXTI_LineCmd = DISABLE; | |||
} | |||
/** | |||
* @brief Generates a Software interrupt on selected EXTI line. | |||
* @param EXTI_Line: specifies the EXTI line on which the software interrupt | |||
* will be generated. | |||
* This parameter can be any combination of EXTI_Linex where x can be (0..22) | |||
* @retval None | |||
*/ | |||
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_EXTI_LINE(EXTI_Line)); | |||
EXTI->SWIER |= EXTI_Line; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup EXTI_Group2 Interrupts and flags management functions | |||
* @brief Interrupts and flags management functions | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### Interrupts and flags management functions ##### | |||
=============================================================================== | |||
@endverbatim | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Checks whether the specified EXTI line flag is set or not. | |||
* @param EXTI_Line: specifies the EXTI line flag to check. | |||
* This parameter can be EXTI_Linex where x can be(0..22) | |||
* @retval The new state of EXTI_Line (SET or RESET). | |||
*/ | |||
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) | |||
{ | |||
FlagStatus bitstatus = RESET; | |||
/* Check the parameters */ | |||
assert_param(IS_GET_EXTI_LINE(EXTI_Line)); | |||
if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) | |||
{ | |||
bitstatus = SET; | |||
} | |||
else | |||
{ | |||
bitstatus = RESET; | |||
} | |||
return bitstatus; | |||
} | |||
/** | |||
* @brief Clears the EXTI's line pending flags. | |||
* @param EXTI_Line: specifies the EXTI lines flags to clear. | |||
* This parameter can be any combination of EXTI_Linex where x can be (0..22) | |||
* @retval None | |||
*/ | |||
void EXTI_ClearFlag(uint32_t EXTI_Line) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_EXTI_LINE(EXTI_Line)); | |||
EXTI->PR = EXTI_Line; | |||
} | |||
/** | |||
* @brief Checks whether the specified EXTI line is asserted or not. | |||
* @param EXTI_Line: specifies the EXTI line to check. | |||
* This parameter can be EXTI_Linex where x can be(0..22) | |||
* @retval The new state of EXTI_Line (SET or RESET). | |||
*/ | |||
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line) | |||
{ | |||
FlagStatus bitstatus = RESET; | |||
/* Check the parameters */ | |||
assert_param(IS_GET_EXTI_LINE(EXTI_Line)); | |||
if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET) | |||
{ | |||
bitstatus = SET; | |||
} | |||
else | |||
{ | |||
bitstatus = RESET; | |||
} | |||
return bitstatus; | |||
} | |||
/** | |||
* @brief Clears the EXTI's line pending bits. | |||
* @param EXTI_Line: specifies the EXTI lines to clear. | |||
* This parameter can be any combination of EXTI_Linex where x can be (0..22) | |||
* @retval None | |||
*/ | |||
void EXTI_ClearITPendingBit(uint32_t EXTI_Line) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_EXTI_LINE(EXTI_Line)); | |||
EXTI->PR = EXTI_Line; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,611 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_gpio.c | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file provides firmware functions to manage the following | |||
* functionalities of the GPIO peripheral: | |||
* + Initialization and Configuration | |||
* + GPIO Read and Write | |||
* + GPIO Alternate functions configuration | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### How to use this driver ##### | |||
=============================================================================== | |||
[..] | |||
(#) Enable the GPIO AHB clock using the following function | |||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); | |||
(#) Configure the GPIO pin(s) using GPIO_Init() | |||
Four possible configuration are available for each pin: | |||
(++) Input: Floating, Pull-up, Pull-down. | |||
(++) Output: Push-Pull (Pull-up, Pull-down or no Pull) | |||
Open Drain (Pull-up, Pull-down or no Pull). In output mode, the speed | |||
is configurable: 2 MHz, 25 MHz, 50 MHz or 100 MHz. | |||
(++) Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull) Open | |||
Drain (Pull-up, Pull-down or no Pull). | |||
(++) Analog: required mode when a pin is to be used as ADC channel or DAC | |||
output. | |||
(#) Peripherals alternate function: | |||
(++) For ADC and DAC, configure the desired pin in analog mode using | |||
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN; | |||
(+++) For other peripherals (TIM, USART...): | |||
(+++) Connect the pin to the desired peripherals' Alternate | |||
Function (AF) using GPIO_PinAFConfig() function | |||
(+++) Configure the desired pin in alternate function mode using | |||
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF | |||
(+++) Select the type, pull-up/pull-down and output speed via | |||
GPIO_PuPd, GPIO_OType and GPIO_Speed members | |||
(+++) Call GPIO_Init() function | |||
(#) To get the level of a pin configured in input mode use GPIO_ReadInputDataBit() | |||
(#) To set/reset the level of a pin configured in output mode use | |||
GPIO_SetBits()/GPIO_ResetBits() | |||
(#) During and just after reset, the alternate functions are not | |||
active and the GPIO pins are configured in input floating mode (except JTAG | |||
pins). | |||
(#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose | |||
(PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has | |||
priority over the GPIO function. | |||
(#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as | |||
general purpose PH0 and PH1, respectively, when the HSE oscillator is off. | |||
The HSE has priority over the GPIO function. | |||
@endverbatim | |||
* | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx_gpio.h" | |||
#include "stm32f4xx_rcc.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @defgroup GPIO | |||
* @brief GPIO driver modules | |||
* @{ | |||
*/ | |||
/* Private typedef -----------------------------------------------------------*/ | |||
/* Private define ------------------------------------------------------------*/ | |||
/* Private macro -------------------------------------------------------------*/ | |||
/* Private variables ---------------------------------------------------------*/ | |||
/* Private function prototypes -----------------------------------------------*/ | |||
/* Private functions ---------------------------------------------------------*/ | |||
/** @defgroup GPIO_Private_Functions | |||
* @{ | |||
*/ | |||
/** @defgroup GPIO_Group1 Initialization and Configuration | |||
* @brief Initialization and Configuration | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### Initialization and Configuration ##### | |||
=============================================================================== | |||
@endverbatim | |||
* @{ | |||
*/ | |||
/** | |||
* @brief De-initializes the GPIOx peripheral registers to their default reset values. | |||
* @note By default, The GPIO pins are configured in input floating mode (except JTAG pins). | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @retval None | |||
*/ | |||
void GPIO_DeInit(GPIO_TypeDef* GPIOx) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
if (GPIOx == GPIOA) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE); | |||
} | |||
else if (GPIOx == GPIOB) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE); | |||
} | |||
else if (GPIOx == GPIOC) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE); | |||
} | |||
else if (GPIOx == GPIOD) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE); | |||
} | |||
else if (GPIOx == GPIOE) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE); | |||
} | |||
else if (GPIOx == GPIOF) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, DISABLE); | |||
} | |||
else if (GPIOx == GPIOG) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, DISABLE); | |||
} | |||
else if (GPIOx == GPIOH) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE); | |||
} | |||
else if (GPIOx == GPIOI) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, DISABLE); | |||
} | |||
else if (GPIOx == GPIOJ) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOJ, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOJ, DISABLE); | |||
} | |||
else | |||
{ | |||
if (GPIOx == GPIOK) | |||
{ | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOK, ENABLE); | |||
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOK, DISABLE); | |||
} | |||
} | |||
} | |||
/** | |||
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains | |||
* the configuration information for the specified GPIO peripheral. | |||
* @retval None | |||
*/ | |||
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) | |||
{ | |||
uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); | |||
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); | |||
assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd)); | |||
/* ------------------------- Configure the port pins ---------------- */ | |||
/*-- GPIO Mode Configuration --*/ | |||
for (pinpos = 0x00; pinpos < 0x10; pinpos++) | |||
{ | |||
pos = ((uint32_t)0x01) << pinpos; | |||
/* Get the port pins position */ | |||
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; | |||
if (currentpin == pos) | |||
{ | |||
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2)); | |||
GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2)); | |||
if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF)) | |||
{ | |||
/* Check Speed mode parameters */ | |||
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); | |||
/* Speed mode configuration */ | |||
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2)); | |||
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2)); | |||
/* Check Output mode parameters */ | |||
assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType)); | |||
/* Output mode configuration*/ | |||
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ; | |||
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos)); | |||
} | |||
/* Pull-up Pull down resistor configuration*/ | |||
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2)); | |||
GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2)); | |||
} | |||
} | |||
} | |||
/** | |||
* @brief Fills each GPIO_InitStruct member with its default value. | |||
* @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized. | |||
* @retval None | |||
*/ | |||
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) | |||
{ | |||
/* Reset GPIO init structure parameters values */ | |||
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; | |||
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; | |||
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz; | |||
GPIO_InitStruct->GPIO_OType = GPIO_OType_PP; | |||
GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL; | |||
} | |||
/** | |||
* @brief Locks GPIO Pins configuration registers. | |||
* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, | |||
* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. | |||
* @note The configuration of the locked GPIO pins can no longer be modified | |||
* until the next reset. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bit to be locked. | |||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15). | |||
* @retval None | |||
*/ | |||
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
__IO uint32_t tmp = 0x00010000; | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GPIO_PIN(GPIO_Pin)); | |||
tmp |= GPIO_Pin; | |||
/* Set LCKK bit */ | |||
GPIOx->LCKR = tmp; | |||
/* Reset LCKK bit */ | |||
GPIOx->LCKR = GPIO_Pin; | |||
/* Set LCKK bit */ | |||
GPIOx->LCKR = tmp; | |||
/* Read LCKK bit*/ | |||
tmp = GPIOx->LCKR; | |||
/* Read LCKK bit*/ | |||
tmp = GPIOx->LCKR; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup GPIO_Group2 GPIO Read and Write | |||
* @brief GPIO Read and Write | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### GPIO Read and Write ##### | |||
=============================================================================== | |||
@endverbatim | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Reads the specified input port pin. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bit to read. | |||
* This parameter can be GPIO_Pin_x where x can be (0..15). | |||
* @retval The input port pin value. | |||
*/ | |||
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
uint8_t bitstatus = 0x00; | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); | |||
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET) | |||
{ | |||
bitstatus = (uint8_t)Bit_SET; | |||
} | |||
else | |||
{ | |||
bitstatus = (uint8_t)Bit_RESET; | |||
} | |||
return bitstatus; | |||
} | |||
/** | |||
* @brief Reads the specified GPIO input data port. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @retval GPIO input data port value. | |||
*/ | |||
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
return ((uint16_t)GPIOx->IDR); | |||
} | |||
/** | |||
* @brief Reads the specified output data port bit. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bit to read. | |||
* This parameter can be GPIO_Pin_x where x can be (0..15). | |||
* @retval The output port pin value. | |||
*/ | |||
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
uint8_t bitstatus = 0x00; | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); | |||
if (((GPIOx->ODR) & GPIO_Pin) != (uint32_t)Bit_RESET) | |||
{ | |||
bitstatus = (uint8_t)Bit_SET; | |||
} | |||
else | |||
{ | |||
bitstatus = (uint8_t)Bit_RESET; | |||
} | |||
return bitstatus; | |||
} | |||
/** | |||
* @brief Reads the specified GPIO output data port. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @retval GPIO output data port value. | |||
*/ | |||
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
return ((uint16_t)GPIOx->ODR); | |||
} | |||
/** | |||
* @brief Sets the selected data port bits. | |||
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify | |||
* accesses. In this way, there is no risk of an IRQ occurring between | |||
* the read and the modify access. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bits to be written. | |||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15). | |||
* @retval None | |||
*/ | |||
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GPIO_PIN(GPIO_Pin)); | |||
GPIOx->BSRRL = GPIO_Pin; | |||
} | |||
/** | |||
* @brief Clears the selected data port bits. | |||
* @note This functions uses GPIOx_BSRR register to allow atomic read/modify | |||
* accesses. In this way, there is no risk of an IRQ occurring between | |||
* the read and the modify access. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bits to be written. | |||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15). | |||
* @retval None | |||
*/ | |||
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GPIO_PIN(GPIO_Pin)); | |||
GPIOx->BSRRH = GPIO_Pin; | |||
} | |||
/** | |||
* @brief Sets or clears the selected data port bit. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: specifies the port bit to be written. | |||
* This parameter can be one of GPIO_Pin_x where x can be (0..15). | |||
* @param BitVal: specifies the value to be written to the selected bit. | |||
* This parameter can be one of the BitAction enum values: | |||
* @arg Bit_RESET: to clear the port pin | |||
* @arg Bit_SET: to set the port pin | |||
* @retval None | |||
*/ | |||
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); | |||
assert_param(IS_GPIO_BIT_ACTION(BitVal)); | |||
if (BitVal != Bit_RESET) | |||
{ | |||
GPIOx->BSRRL = GPIO_Pin; | |||
} | |||
else | |||
{ | |||
GPIOx->BSRRH = GPIO_Pin ; | |||
} | |||
} | |||
/** | |||
* @brief Writes data to the specified GPIO data port. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param PortVal: specifies the value to be written to the port output data register. | |||
* @retval None | |||
*/ | |||
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
GPIOx->ODR = PortVal; | |||
} | |||
/** | |||
* @brief Toggles the specified GPIO pins.. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_Pin: Specifies the pins to be toggled. | |||
* @retval None | |||
*/ | |||
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
GPIOx->ODR ^= GPIO_Pin; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** @defgroup GPIO_Group3 GPIO Alternate functions configuration function | |||
* @brief GPIO Alternate functions configuration function | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### GPIO Alternate functions configuration function ##### | |||
=============================================================================== | |||
@endverbatim | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Changes the mapping of the specified pin. | |||
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices | |||
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices. | |||
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices. | |||
* @param GPIO_PinSource: specifies the pin for the Alternate function. | |||
* This parameter can be GPIO_PinSourcex where x can be (0..15). | |||
* @param GPIO_AFSelection: selects the pin to used as Alternate function. | |||
* This parameter can be one of the following values: | |||
* @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset) | |||
* @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset) | |||
* @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset) | |||
* @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset) | |||
* @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset) | |||
* @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1 | |||
* @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1 | |||
* @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2 | |||
* @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2 | |||
* @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2 | |||
* @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3 | |||
* @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3 | |||
* @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3 | |||
* @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3 | |||
* @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4 | |||
* @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4 | |||
* @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4 | |||
* @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5 | |||
* @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5 | |||
* @arg GPIO_AF_SPI4: Connect SPI4 pins to AF5 | |||
* @arg GPIO_AF_SPI5: Connect SPI5 pins to AF5 | |||
* @arg GPIO_AF_SPI6: Connect SPI6 pins to AF5 | |||
* @arg GPIO_AF_SAI1: Connect SAI1 pins to AF6 for STM32F42xxx/43xxx devices. | |||
* @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6 | |||
* @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7 | |||
* @arg GPIO_AF_USART1: Connect USART1 pins to AF7 | |||
* @arg GPIO_AF_USART2: Connect USART2 pins to AF7 | |||
* @arg GPIO_AF_USART3: Connect USART3 pins to AF7 | |||
* @arg GPIO_AF_UART4: Connect UART4 pins to AF8 | |||
* @arg GPIO_AF_UART5: Connect UART5 pins to AF8 | |||
* @arg GPIO_AF_USART6: Connect USART6 pins to AF8 | |||
* @arg GPIO_AF_UART7: Connect UART7 pins to AF8 | |||
* @arg GPIO_AF_UART8: Connect UART8 pins to AF8 | |||
* @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9 | |||
* @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9 | |||
* @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9 | |||
* @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9 | |||
* @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9 | |||
* @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10 | |||
* @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10 | |||
* @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11 | |||
* @arg GPIO_AF_FSMC: Connect FSMC pins to AF12 | |||
* @arg GPIO_AF_FMC: Connect FMC pins to AF12 for STM32F42xxx/43xxx devices. | |||
* @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12 | |||
* @arg GPIO_AF_SDIO: Connect SDIO pins to AF12 | |||
* @arg GPIO_AF_DCMI: Connect DCMI pins to AF13 | |||
* @arg GPIO_AF_LTDC: Connect LTDC pins to AF14 for STM32F429xx/439xx devices. | |||
* @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15 | |||
* @retval None | |||
*/ | |||
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) | |||
{ | |||
uint32_t temp = 0x00; | |||
uint32_t temp_2 = 0x00; | |||
/* Check the parameters */ | |||
assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); | |||
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource)); | |||
assert_param(IS_GPIO_AF(GPIO_AF)); | |||
temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; | |||
GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ; | |||
temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp; | |||
GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,240 @@ | |||
/** | |||
****************************************************************************** | |||
* @file stm32f4xx_syscfg.c | |||
* @author MCD Application Team | |||
* @version V1.4.0 | |||
* @date 04-August-2014 | |||
* @brief This file provides firmware functions to manage the SYSCFG peripheral. | |||
* | |||
@verbatim | |||
=============================================================================== | |||
##### How to use this driver ##### | |||
=============================================================================== | |||
[..] This driver provides functions for: | |||
(#) Remapping the memory accessible in the code area using SYSCFG_MemoryRemapConfig() | |||
(#) Swapping the internal flash Bank1 and Bank2 this features is only visible for | |||
STM32F42xxx/43xxx devices Devices. | |||
(#) Manage the EXTI lines connection to the GPIOs using SYSCFG_EXTILineConfig() | |||
(#) Select the ETHERNET media interface (RMII/RII) using SYSCFG_ETH_MediaInterfaceConfig() | |||
-@- SYSCFG APB clock must be enabled to get write access to SYSCFG registers, | |||
using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); | |||
@endverbatim | |||
****************************************************************************** | |||
* @attention | |||
* | |||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> | |||
* | |||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
* | |||
* 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. | |||
* | |||
****************************************************************************** | |||
*/ | |||
/* Includes ------------------------------------------------------------------*/ | |||
#include "stm32f4xx_syscfg.h" | |||
#include "stm32f4xx_rcc.h" | |||
/** @addtogroup STM32F4xx_StdPeriph_Driver | |||
* @{ | |||
*/ | |||
/** @defgroup SYSCFG | |||
* @brief SYSCFG driver modules | |||
* @{ | |||
*/ | |||
/* Private typedef -----------------------------------------------------------*/ | |||
/* Private define ------------------------------------------------------------*/ | |||
/* ------------ RCC registers bit address in the alias region ----------- */ | |||
#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE) | |||
/* --- MEMRMP Register ---*/ | |||
/* Alias word address of UFB_MODE bit */ | |||
#define MEMRMP_OFFSET SYSCFG_OFFSET | |||
#define UFB_MODE_BitNumber ((uint8_t)0x8) | |||
#define UFB_MODE_BB (PERIPH_BB_BASE + (MEMRMP_OFFSET * 32) + (UFB_MODE_BitNumber * 4)) | |||
/* --- PMC Register ---*/ | |||
/* Alias word address of MII_RMII_SEL bit */ | |||
#define PMC_OFFSET (SYSCFG_OFFSET + 0x04) | |||
#define MII_RMII_SEL_BitNumber ((uint8_t)0x17) | |||
#define PMC_MII_RMII_SEL_BB (PERIPH_BB_BASE + (PMC_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4)) | |||
/* --- CMPCR Register ---*/ | |||
/* Alias word address of CMP_PD bit */ | |||
#define CMPCR_OFFSET (SYSCFG_OFFSET + 0x20) | |||
#define CMP_PD_BitNumber ((uint8_t)0x00) | |||
#define CMPCR_CMP_PD_BB (PERIPH_BB_BASE + (CMPCR_OFFSET * 32) + (CMP_PD_BitNumber * 4)) | |||
/* Private macro -------------------------------------------------------------*/ | |||
/* Private variables ---------------------------------------------------------*/ | |||
/* Private function prototypes -----------------------------------------------*/ | |||
/* Private functions ---------------------------------------------------------*/ | |||
/** @defgroup SYSCFG_Private_Functions | |||
* @{ | |||
*/ | |||
/** | |||
* @brief Deinitializes the Alternate Functions (remap and EXTI configuration) | |||
* registers to their default reset values. | |||
* @param None | |||
* @retval None | |||
*/ | |||
void SYSCFG_DeInit(void) | |||
{ | |||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE); | |||
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE); | |||
} | |||
/** | |||
* @brief Changes the mapping of the specified pin. | |||
* @param SYSCFG_Memory: selects the memory remapping. | |||
* This parameter can be one of the following values: | |||
* @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000 | |||
* @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000 | |||
* @arg SYSCFG_MemoryRemap_FSMC: FSMC (Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 for STM32F405xx/407xx and STM32F415xx/417xx devices. | |||
* @arg SYSCFG_MemoryRemap_FMC: FMC (Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 for STM32F42xxx/43xxx devices. | |||
* @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM (112kB) mapped at 0x00000000 | |||
* @arg SYSCFG_MemoryRemap_SDRAM: FMC (External SDRAM) mapped at 0x00000000 for STM32F42xxx/43xxx devices. | |||
* @retval None | |||
*/ | |||
void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap)); | |||
SYSCFG->MEMRMP = SYSCFG_MemoryRemap; | |||
} | |||
/** | |||
* @brief Enables or disables the Interal FLASH Bank Swapping. | |||
* | |||
* @note This function can be used only for STM32F42xxx/43xxx devices. | |||
* | |||
* @param NewState: new state of Interal FLASH Bank swapping. | |||
* This parameter can be one of the following values: | |||
* @arg ENABLE: Flash Bank2 mapped at 0x08000000 (and aliased @0x00000000) | |||
* and Flash Bank1 mapped at 0x08100000 (and aliased at 0x00100000) | |||
* @arg DISABLE:(the default state) Flash Bank1 mapped at 0x08000000 (and aliased @0x0000 0000) | |||
and Flash Bank2 mapped at 0x08100000 (and aliased at 0x00100000) | |||
* @retval None | |||
*/ | |||
void SYSCFG_MemorySwappingBank(FunctionalState NewState) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_FUNCTIONAL_STATE(NewState)); | |||
*(__IO uint32_t *) UFB_MODE_BB = (uint32_t)NewState; | |||
} | |||
/** | |||
* @brief Selects the GPIO pin used as EXTI Line. | |||
* @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for | |||
* EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I) | |||
* for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H) | |||
* for STM32401xx devices. | |||
* | |||
* @param EXTI_PinSourcex: specifies the EXTI line to be configured. | |||
* This parameter can be EXTI_PinSourcex where x can be (0..15, except | |||
* for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx | |||
* and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can | |||
* be (0..7) for STM32F42xxx/43xxx devices. | |||
* | |||
* @retval None | |||
*/ | |||
void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex) | |||
{ | |||
uint32_t tmp = 0x00; | |||
/* Check the parameters */ | |||
assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx)); | |||
assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex)); | |||
tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)); | |||
SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp; | |||
SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03))); | |||
} | |||
/** | |||
* @brief Selects the ETHERNET media interface | |||
* @param SYSCFG_ETH_MediaInterface: specifies the Media Interface mode. | |||
* This parameter can be one of the following values: | |||
* @arg SYSCFG_ETH_MediaInterface_MII: MII mode selected | |||
* @arg SYSCFG_ETH_MediaInterface_RMII: RMII mode selected | |||
* @retval None | |||
*/ | |||
void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface) | |||
{ | |||
assert_param(IS_SYSCFG_ETH_MEDIA_INTERFACE(SYSCFG_ETH_MediaInterface)); | |||
/* Configure MII_RMII selection bit */ | |||
*(__IO uint32_t *) PMC_MII_RMII_SEL_BB = SYSCFG_ETH_MediaInterface; | |||
} | |||
/** | |||
* @brief Enables or disables the I/O Compensation Cell. | |||
* @note The I/O compensation cell can be used only when the device supply | |||
* voltage ranges from 2.4 to 3.6 V. | |||
* @param NewState: new state of the I/O Compensation Cell. | |||
* This parameter can be one of the following values: | |||
* @arg ENABLE: I/O compensation cell enabled | |||
* @arg DISABLE: I/O compensation cell power-down mode | |||
* @retval None | |||
*/ | |||
void SYSCFG_CompensationCellCmd(FunctionalState NewState) | |||
{ | |||
/* Check the parameters */ | |||
assert_param(IS_FUNCTIONAL_STATE(NewState)); | |||
*(__IO uint32_t *) CMPCR_CMP_PD_BB = (uint32_t)NewState; | |||
} | |||
/** | |||
* @brief Checks whether the I/O Compensation Cell ready flag is set or not. | |||
* @param None | |||
* @retval The new state of the I/O Compensation Cell ready flag (SET or RESET) | |||
*/ | |||
FlagStatus SYSCFG_GetCompensationCellStatus(void) | |||
{ | |||
FlagStatus bitstatus = RESET; | |||
if ((SYSCFG->CMPCR & SYSCFG_CMPCR_READY ) != (uint32_t)RESET) | |||
{ | |||
bitstatus = SET; | |||
} | |||
else | |||
{ | |||
bitstatus = RESET; | |||
} | |||
return bitstatus; | |||
} | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/** | |||
* @} | |||
*/ | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,40 @@ | |||
@REM This batch file has been generated by the IAR Embedded Workbench | |||
@REM C-SPY Debugger, as an aid to preparing a command line for running | |||
@REM the cspybat command line utility using the appropriate settings. | |||
@REM | |||
@REM Note that this file is generated every time a new debug session | |||
@REM is initialized, so you may want to move or rename the file before | |||
@REM making changes. | |||
@REM | |||
@REM You can launch cspybat by typing the name of this batch file followed | |||
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). | |||
@REM | |||
@REM Read about available command line parameters in the C-SPY Debugging | |||
@REM Guide. Hints about additional command line parameters that may be | |||
@REM useful in specific cases: | |||
@REM --download_only Downloads a code image without starting a debug | |||
@REM session afterwards. | |||
@REM --silent Omits the sign-on message. | |||
@REM --timeout Limits the maximum allowed execution time. | |||
@REM | |||
@echo off | |||
if not "%~1" == "" goto debugFile | |||
@echo on | |||
"F:\AAAAA\IAR\common\bin\cspybat" -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.general.xcl" --backend -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.driver.xcl" | |||
@echo off | |||
goto end | |||
:debugFile | |||
@echo on | |||
"F:\AAAAA\IAR\common\bin\cspybat" -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.general.xcl" "--debug_file=%~1" --backend -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.driver.xcl" | |||
@echo off | |||
:end |
@@ -0,0 +1,31 @@ | |||
param([String]$debugfile = ""); | |||
# This powershell file has been generated by the IAR Embedded Workbench | |||
# C - SPY Debugger, as an aid to preparing a command line for running | |||
# the cspybat command line utility using the appropriate settings. | |||
# | |||
# Note that this file is generated every time a new debug session | |||
# is initialized, so you may want to move or rename the file before | |||
# making changes. | |||
# | |||
# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed | |||
# by the name of the debug file (usually an ELF / DWARF or UBROF file). | |||
# | |||
# Read about available command line parameters in the C - SPY Debugging | |||
# Guide. Hints about additional command line parameters that may be | |||
# useful in specific cases : | |||
# --download_only Downloads a code image without starting a debug | |||
# session afterwards. | |||
# --silent Omits the sign - on message. | |||
# --timeout Limits the maximum allowed execution time. | |||
# | |||
if ($debugfile -eq "") | |||
{ | |||
& "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.general.xcl" --backend -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.driver.xcl" | |||
} | |||
else | |||
{ | |||
& "F:\AAAAA\IAR\common\bin\cspybat" -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.general.xcl" --debug_file=$debugfile --backend -f "F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\settings\task01.Debug.driver.xcl" | |||
} |
@@ -0,0 +1,29 @@ | |||
"--endian=little" | |||
"--cpu=Cortex-M4" | |||
"--fpu=VFPv4_SP" | |||
"-p" | |||
"F:\AAAAA\IAR\arm\CONFIG\debugger\ST\STM32F407IG.ddf" | |||
"--semihosting" | |||
"--device=STM32F407IG" | |||
"--drv_interface=SWD" | |||
"--stlink_reset_strategy=0,0" | |||
"--drv_swo_clock_setup=168000000,0,2000000" | |||
"--drv_catch_exceptions=0x000" | |||
"--drv_debug_ap=0" | |||
"--stlink_probe=stlinkv2" | |||
@@ -0,0 +1,15 @@ | |||
"F:\AAAAA\IAR\arm\bin\armproc.dll" | |||
"F:\AAAAA\IAR\arm\bin\armstlink2.dll" | |||
"F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\Debug\Exe\task01.out" | |||
--plugin="F:\AAAAA\IAR\arm\bin\armbat.dll" | |||
--device_macro="F:\AAAAA\IAR\arm\config\debugger\ST\STM32F4xx.dmac" | |||
--flash_loader="F:\AAAAA\IAR\arm\config\flashloader\ST\FlashSTM32F4xxx.board" | |||
@@ -0,0 +1,13 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<crun> | |||
<version>1</version> | |||
<filter_entries> | |||
<filter index="0" type="default"> | |||
<type>*</type> | |||
<start_file>*</start_file> | |||
<end_file>*</end_file> | |||
<action_debugger>0</action_debugger> | |||
<action_log>1</action_log> | |||
</filter> | |||
</filter_entries> | |||
</crun> |
@@ -0,0 +1,155 @@ | |||
<?xml version="1.0"?> | |||
<settings> | |||
<Stack> | |||
<FillEnabled>0</FillEnabled> | |||
<OverflowWarningsEnabled>1</OverflowWarningsEnabled> | |||
<WarningThreshold>90</WarningThreshold> | |||
<SpWarningsEnabled>1</SpWarningsEnabled> | |||
<WarnLogOnly>1</WarnLogOnly> | |||
<UseTrigger>1</UseTrigger> | |||
<TriggerName>main</TriggerName> | |||
<LimitSize>0</LimitSize> | |||
<ByteLimit>50</ByteLimit> | |||
</Stack> | |||
<Interrupts> | |||
<Enabled>1</Enabled> | |||
</Interrupts> | |||
<MemConfig> | |||
<Base>1</Base> | |||
<Manual>0</Manual> | |||
<Ddf>1</Ddf> | |||
<TypeViol>0</TypeViol> | |||
<Stop>1</Stop> | |||
</MemConfig> | |||
<Trace1> | |||
<Enabled>0</Enabled> | |||
<ShowSource>1</ShowSource> | |||
</Trace1> | |||
<Simulator> | |||
<Freq>10000000</Freq> | |||
<FreqHi>0</FreqHi> | |||
<MultiCoreRunAll>1</MultiCoreRunAll> | |||
</Simulator> | |||
<StLinkDriver> | |||
<stlinkserialNo>35452557</stlinkserialNo> | |||
<stlinkfoundProbes /> | |||
<stlinkResetStyle>0</stlinkResetStyle> | |||
<stlinkResetStrategy>0</stlinkResetStrategy> | |||
<CStepIntDis>_ 0</CStepIntDis> | |||
<LeaveTargetRunning>_ 0</LeaveTargetRunning> | |||
</StLinkDriver> | |||
<DebugChecksum> | |||
<Checksum>1117100520</Checksum> | |||
</DebugChecksum> | |||
<Exceptions> | |||
<StopOnUncaught>_ 0</StopOnUncaught> | |||
<StopOnThrow>_ 0</StopOnThrow> | |||
</Exceptions> | |||
<Disassembly> | |||
<InstrCount>0</InstrCount> | |||
<MixedMode>1</MixedMode> | |||
</Disassembly> | |||
<CodeCoverage> | |||
<Enabled>0</Enabled> | |||
<ShowSource>0</ShowSource> | |||
<HideCovered>0</HideCovered> | |||
</CodeCoverage> | |||
<CallStack> | |||
<ShowArgs>0</ShowArgs> | |||
</CallStack> | |||
<SWOTraceHWSettings> | |||
<OverrideDefaultClocks>0</OverrideDefaultClocks> | |||
<CpuClock>168000000</CpuClock> | |||
<ClockAutoDetect>0</ClockAutoDetect> | |||
<ClockWanted>2000000</ClockWanted> | |||
<JtagSpeed>2000000</JtagSpeed> | |||
<Prescaler>84</Prescaler> | |||
<TimeStampPrescIndex>0</TimeStampPrescIndex> | |||
<TimeStampPrescData>0</TimeStampPrescData> | |||
<PcSampCYCTAP>1</PcSampCYCTAP> | |||
<PcSampPOSTCNT>15</PcSampPOSTCNT> | |||
<PcSampIndex>0</PcSampIndex> | |||
<DataLogMode>0</DataLogMode> | |||
<ITMportsEnable>0</ITMportsEnable> | |||
<ITMportsTermIO>0</ITMportsTermIO> | |||
<ITMportsLogFile>0</ITMportsLogFile> | |||
<ITMlogFile>$PROJ_DIR$\ITM.log</ITMlogFile> | |||
</SWOTraceHWSettings> | |||
<Trace2> | |||
<Enabled>0</Enabled> | |||
<ShowSource>0</ShowSource> | |||
</Trace2> | |||
<SWOTraceWindow> | |||
<PcSampling>0</PcSampling> | |||
<InterruptLogs>0</InterruptLogs> | |||
<ForcedTimeStamps>0</ForcedTimeStamps> | |||
<EventCPI>0</EventCPI> | |||
<EventEXC>0</EventEXC> | |||
<EventFOLD>0</EventFOLD> | |||
<EventLSU>0</EventLSU> | |||
<EventSLEEP>0</EventSLEEP> | |||
</SWOTraceWindow> | |||
<DataLog> | |||
<LogEnabled>0</LogEnabled> | |||
<GraphEnabled>0</GraphEnabled> | |||
<ShowTimeLog>1</ShowTimeLog> | |||
<SumEnabled>0</SumEnabled> | |||
<ShowTimeSum>1</ShowTimeSum> | |||
</DataLog> | |||
<InterruptLog> | |||
<LogEnabled>0</LogEnabled> | |||
<GraphEnabled>0</GraphEnabled> | |||
<ShowTimeLog>1</ShowTimeLog> | |||
<SumEnabled>0</SumEnabled> | |||
<ShowTimeSum>1</ShowTimeSum> | |||
<SumSortOrder>0</SumSortOrder> | |||
</InterruptLog> | |||
<EventLog> | |||
<Title_0>Ch3</Title_0> | |||
<Symbol_0>0 0 1</Symbol_0> | |||
<Title_1>Ch2</Title_1> | |||
<Symbol_1>0 0 1</Symbol_1> | |||
<Title_2>Ch1</Title_2> | |||
<Symbol_2>0 0 1</Symbol_2> | |||
<Title_3>Ch0</Title_3> | |||
<Symbol_3>0 0 1</Symbol_3> | |||
<LogEnabled>0</LogEnabled> | |||
<GraphEnabled>0</GraphEnabled> | |||
<ShowTimeLog>1</ShowTimeLog> | |||
<SumEnabled>0</SumEnabled> | |||
<ShowTimeSum>1</ShowTimeSum> | |||
<SumSortOrder>0</SumSortOrder> | |||
</EventLog> | |||
<TermIOLog> | |||
<LoggingEnabled>_ 0</LoggingEnabled> | |||
<LogFile>_ ""</LogFile> | |||
</TermIOLog> | |||
<LogFile> | |||
<LoggingEnabled>_ 0</LoggingEnabled> | |||
<LogFile>_ ""</LogFile> | |||
<Category>_ 0</Category> | |||
</LogFile> | |||
<DriverProfiling> | |||
<Enabled>0</Enabled> | |||
<Mode>3</Mode> | |||
<Graph>0</Graph> | |||
<Symbiont>0</Symbiont> | |||
<Exclusions /> | |||
</DriverProfiling> | |||
<CallStackLog> | |||
<Enabled>0</Enabled> | |||
</CallStackLog> | |||
<CallStackStripe> | |||
<ShowTiming>1</ShowTiming> | |||
</CallStackStripe> | |||
<DisassembleMode> | |||
<mode>0</mode> | |||
</DisassembleMode> | |||
<Breakpoints2> | |||
<Count>0</Count> | |||
</Breakpoints2> | |||
<Aliases> | |||
<Count>0</Count> | |||
<SuppressDialog>0</SuppressDialog> | |||
</Aliases> | |||
</settings> |
@@ -0,0 +1,636 @@ | |||
;/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** | |||
;* File Name : startup_stm32f40_41xxx.s | |||
;* Author : MCD Application Team | |||
;* @version : V1.4.0 | |||
;* @date : 04-August-2014 | |||
;* Description : STM32F40xxx/41xxx devices vector table for EWARM toolchain. | |||
;* This module performs: | |||
;* - Set the initial SP | |||
;* - Set the initial PC == _iar_program_start, | |||
;* - Set the vector table entries with the exceptions ISR | |||
;* address. | |||
;* - Configure the system clock and the external SRAM mounted on | |||
;* STM324xG-EVAL board to be used as data memory (optional, | |||
;* to be enabled by user) | |||
;* - Branches to main in the C library (which eventually | |||
;* calls main()). | |||
;* After Reset the Cortex-M4 processor is in Thread mode, | |||
;* priority is Privileged, and the Stack is set to Main. | |||
;******************************************************************************** | |||
;* | |||
;* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 | |||
;* | |||
;* 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. | |||
;* | |||
;*******************************************************************************/ | |||
; | |||
; | |||
; The modules in this file are included in the libraries, and may be replaced | |||
; by any user-defined modules that define the PUBLIC symbol _program_start or | |||
; a user defined start symbol. | |||
; To override the cstartup defined in the library, simply add your modified | |||
; version to the workbench project. | |||
; | |||
; The vector table is normally located at address 0. | |||
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. | |||
; The name "__vector_table" has special meaning for C-SPY: | |||
; it is where the SP start value is found, and the NVIC vector | |||
; table register (VTOR) is initialized to this address if != 0. | |||
; | |||
; Cortex-M version | |||
; | |||
MODULE ?cstartup | |||
;; Forward declaration of sections. | |||
SECTION CSTACK:DATA:NOROOT(3) | |||
SECTION .intvec:CODE:NOROOT(2) | |||
EXTERN __iar_program_start | |||
EXTERN SystemInit | |||
PUBLIC __vector_table | |||
DATA | |||
__vector_table | |||
DCD sfe(CSTACK) | |||
DCD Reset_Handler ; Reset Handler | |||
DCD NMI_Handler ; NMI Handler | |||
DCD HardFault_Handler ; Hard Fault Handler | |||
DCD MemManage_Handler ; MPU Fault Handler | |||
DCD BusFault_Handler ; Bus Fault Handler | |||
DCD UsageFault_Handler ; Usage Fault Handler | |||
DCD 0 ; Reserved | |||
DCD 0 ; Reserved | |||
DCD 0 ; Reserved | |||
DCD 0 ; Reserved | |||
DCD SVC_Handler ; SVCall Handler | |||
DCD DebugMon_Handler ; Debug Monitor Handler | |||
DCD 0 ; Reserved | |||
DCD OS_CPU_PendSVHandler ; PendSV Handler | |||
DCD SysTick_Handler ; SysTick Handler | |||
; External Interrupts | |||
DCD WWDG_IRQHandler ; Window WatchDog | |||
DCD PVD_IRQHandler ; PVD through EXTI Line detection | |||
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line | |||
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line | |||
DCD FLASH_IRQHandler ; FLASH | |||
DCD RCC_IRQHandler ; RCC | |||
DCD EXTI0_IRQHandler ; EXTI Line0 | |||
DCD EXTI1_IRQHandler ; EXTI Line1 | |||
DCD EXTI2_IRQHandler ; EXTI Line2 | |||
DCD EXTI3_IRQHandler ; EXTI Line3 | |||
DCD EXTI4_IRQHandler ; EXTI Line4 | |||
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 | |||
DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 | |||
DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 | |||
DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 | |||
DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 | |||
DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 | |||
DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 | |||
DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s | |||
DCD CAN1_TX_IRQHandler ; CAN1 TX | |||
DCD CAN1_RX0_IRQHandler ; CAN1 RX0 | |||
DCD CAN1_RX1_IRQHandler ; CAN1 RX1 | |||
DCD CAN1_SCE_IRQHandler ; CAN1 SCE | |||
DCD EXTI9_5_IRQHandler ; External Line[9:5]s | |||
DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9 | |||
DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10 | |||
DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11 | |||
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare | |||
DCD TIM2_IRQHandler ; TIM2 | |||
DCD TIM3_IRQHandler ; TIM3 | |||
DCD TIM4_IRQHandler ; TIM4 | |||
DCD I2C1_EV_IRQHandler ; I2C1 Event | |||
DCD I2C1_ER_IRQHandler ; I2C1 Error | |||
DCD I2C2_EV_IRQHandler ; I2C2 Event | |||
DCD I2C2_ER_IRQHandler ; I2C2 Error | |||
DCD SPI1_IRQHandler ; SPI1 | |||
DCD SPI2_IRQHandler ; SPI2 | |||
DCD USART1_IRQHandler ; USART1 | |||
DCD USART2_IRQHandler ; USART2 | |||
DCD USART3_IRQHandler ; USART3 | |||
DCD EXTI15_10_IRQHandler ; External Line[15:10]s | |||
DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line | |||
DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line | |||
DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12 | |||
DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13 | |||
DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14 | |||
DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare | |||
DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 | |||
DCD FSMC_IRQHandler ; FSMC | |||
DCD SDIO_IRQHandler ; SDIO | |||
DCD TIM5_IRQHandler ; TIM5 | |||
DCD SPI3_IRQHandler ; SPI3 | |||
DCD UART4_IRQHandler ; UART4 | |||
DCD UART5_IRQHandler ; UART5 | |||
DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors | |||
DCD TIM7_IRQHandler ; TIM7 | |||
DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 | |||
DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 | |||
DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 | |||
DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 | |||
DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 | |||
DCD ETH_IRQHandler ; Ethernet | |||
DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line | |||
DCD CAN2_TX_IRQHandler ; CAN2 TX | |||
DCD CAN2_RX0_IRQHandler ; CAN2 RX0 | |||
DCD CAN2_RX1_IRQHandler ; CAN2 RX1 | |||
DCD CAN2_SCE_IRQHandler ; CAN2 SCE | |||
DCD OTG_FS_IRQHandler ; USB OTG FS | |||
DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 | |||
DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 | |||
DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 | |||
DCD USART6_IRQHandler ; USART6 | |||
DCD I2C3_EV_IRQHandler ; I2C3 event | |||
DCD I2C3_ER_IRQHandler ; I2C3 error | |||
DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out | |||
DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In | |||
DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI | |||
DCD OTG_HS_IRQHandler ; USB OTG HS | |||
DCD DCMI_IRQHandler ; DCMI | |||
DCD CRYP_IRQHandler ; CRYP crypto | |||
DCD HASH_RNG_IRQHandler ; Hash and Rng | |||
DCD FPU_IRQHandler ; FPU | |||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||
;; | |||
;; Default interrupt handlers. | |||
;; | |||
THUMB | |||
PUBWEAK Reset_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(2) | |||
Reset_Handler | |||
LDR R0, =SystemInit | |||
BLX R0 | |||
LDR R0, =__iar_program_start | |||
BX R0 | |||
PUBWEAK NMI_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
NMI_Handler | |||
B NMI_Handler | |||
PUBWEAK HardFault_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
HardFault_Handler | |||
B HardFault_Handler | |||
PUBWEAK MemManage_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
MemManage_Handler | |||
B MemManage_Handler | |||
PUBWEAK BusFault_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
BusFault_Handler | |||
B BusFault_Handler | |||
PUBWEAK UsageFault_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
UsageFault_Handler | |||
B UsageFault_Handler | |||
PUBWEAK SVC_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SVC_Handler | |||
B SVC_Handler | |||
PUBWEAK DebugMon_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DebugMon_Handler | |||
B DebugMon_Handler | |||
PUBWEAK OS_CPU_PendSVHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OS_CPU_PendSVHandler | |||
B OS_CPU_PendSVHandler | |||
PUBWEAK SysTick_Handler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SysTick_Handler | |||
B SysTick_Handler | |||
PUBWEAK WWDG_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
WWDG_IRQHandler | |||
B WWDG_IRQHandler | |||
PUBWEAK PVD_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
PVD_IRQHandler | |||
B PVD_IRQHandler | |||
PUBWEAK TAMP_STAMP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TAMP_STAMP_IRQHandler | |||
B TAMP_STAMP_IRQHandler | |||
PUBWEAK RTC_WKUP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
RTC_WKUP_IRQHandler | |||
B RTC_WKUP_IRQHandler | |||
PUBWEAK FLASH_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
FLASH_IRQHandler | |||
B FLASH_IRQHandler | |||
PUBWEAK RCC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
RCC_IRQHandler | |||
B RCC_IRQHandler | |||
PUBWEAK EXTI0_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI0_IRQHandler | |||
B EXTI0_IRQHandler | |||
PUBWEAK EXTI1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI1_IRQHandler | |||
B EXTI1_IRQHandler | |||
PUBWEAK EXTI2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI2_IRQHandler | |||
B EXTI2_IRQHandler | |||
PUBWEAK EXTI3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI3_IRQHandler | |||
B EXTI3_IRQHandler | |||
PUBWEAK EXTI4_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI4_IRQHandler | |||
B EXTI4_IRQHandler | |||
PUBWEAK DMA1_Stream0_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream0_IRQHandler | |||
B DMA1_Stream0_IRQHandler | |||
PUBWEAK DMA1_Stream1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream1_IRQHandler | |||
B DMA1_Stream1_IRQHandler | |||
PUBWEAK DMA1_Stream2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream2_IRQHandler | |||
B DMA1_Stream2_IRQHandler | |||
PUBWEAK DMA1_Stream3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream3_IRQHandler | |||
B DMA1_Stream3_IRQHandler | |||
PUBWEAK DMA1_Stream4_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream4_IRQHandler | |||
B DMA1_Stream4_IRQHandler | |||
PUBWEAK DMA1_Stream5_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream5_IRQHandler | |||
B DMA1_Stream5_IRQHandler | |||
PUBWEAK DMA1_Stream6_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream6_IRQHandler | |||
B DMA1_Stream6_IRQHandler | |||
PUBWEAK ADC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
ADC_IRQHandler | |||
B ADC_IRQHandler | |||
PUBWEAK CAN1_TX_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN1_TX_IRQHandler | |||
B CAN1_TX_IRQHandler | |||
PUBWEAK CAN1_RX0_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN1_RX0_IRQHandler | |||
B CAN1_RX0_IRQHandler | |||
PUBWEAK CAN1_RX1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN1_RX1_IRQHandler | |||
B CAN1_RX1_IRQHandler | |||
PUBWEAK CAN1_SCE_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN1_SCE_IRQHandler | |||
B CAN1_SCE_IRQHandler | |||
PUBWEAK EXTI9_5_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI9_5_IRQHandler | |||
B EXTI9_5_IRQHandler | |||
PUBWEAK TIM1_BRK_TIM9_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM1_BRK_TIM9_IRQHandler | |||
B TIM1_BRK_TIM9_IRQHandler | |||
PUBWEAK TIM1_UP_TIM10_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM1_UP_TIM10_IRQHandler | |||
B TIM1_UP_TIM10_IRQHandler | |||
PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM1_TRG_COM_TIM11_IRQHandler | |||
B TIM1_TRG_COM_TIM11_IRQHandler | |||
PUBWEAK TIM1_CC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM1_CC_IRQHandler | |||
B TIM1_CC_IRQHandler | |||
PUBWEAK TIM2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM2_IRQHandler | |||
B TIM2_IRQHandler | |||
PUBWEAK TIM3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM3_IRQHandler | |||
B TIM3_IRQHandler | |||
PUBWEAK TIM4_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM4_IRQHandler | |||
B TIM4_IRQHandler | |||
PUBWEAK I2C1_EV_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C1_EV_IRQHandler | |||
B I2C1_EV_IRQHandler | |||
PUBWEAK I2C1_ER_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C1_ER_IRQHandler | |||
B I2C1_ER_IRQHandler | |||
PUBWEAK I2C2_EV_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C2_EV_IRQHandler | |||
B I2C2_EV_IRQHandler | |||
PUBWEAK I2C2_ER_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C2_ER_IRQHandler | |||
B I2C2_ER_IRQHandler | |||
PUBWEAK SPI1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SPI1_IRQHandler | |||
B SPI1_IRQHandler | |||
PUBWEAK SPI2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SPI2_IRQHandler | |||
B SPI2_IRQHandler | |||
PUBWEAK USART1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
USART1_IRQHandler | |||
B USART1_IRQHandler | |||
PUBWEAK USART2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
USART2_IRQHandler | |||
B USART2_IRQHandler | |||
PUBWEAK USART3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
USART3_IRQHandler | |||
B USART3_IRQHandler | |||
PUBWEAK EXTI15_10_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
EXTI15_10_IRQHandler | |||
B EXTI15_10_IRQHandler | |||
PUBWEAK RTC_Alarm_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
RTC_Alarm_IRQHandler | |||
B RTC_Alarm_IRQHandler | |||
PUBWEAK OTG_FS_WKUP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_FS_WKUP_IRQHandler | |||
B OTG_FS_WKUP_IRQHandler | |||
PUBWEAK TIM8_BRK_TIM12_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM8_BRK_TIM12_IRQHandler | |||
B TIM8_BRK_TIM12_IRQHandler | |||
PUBWEAK TIM8_UP_TIM13_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM8_UP_TIM13_IRQHandler | |||
B TIM8_UP_TIM13_IRQHandler | |||
PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM8_TRG_COM_TIM14_IRQHandler | |||
B TIM8_TRG_COM_TIM14_IRQHandler | |||
PUBWEAK TIM8_CC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM8_CC_IRQHandler | |||
B TIM8_CC_IRQHandler | |||
PUBWEAK DMA1_Stream7_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA1_Stream7_IRQHandler | |||
B DMA1_Stream7_IRQHandler | |||
PUBWEAK FSMC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
FSMC_IRQHandler | |||
B FSMC_IRQHandler | |||
PUBWEAK SDIO_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SDIO_IRQHandler | |||
B SDIO_IRQHandler | |||
PUBWEAK TIM5_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM5_IRQHandler | |||
B TIM5_IRQHandler | |||
PUBWEAK SPI3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
SPI3_IRQHandler | |||
B SPI3_IRQHandler | |||
PUBWEAK UART4_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
UART4_IRQHandler | |||
B UART4_IRQHandler | |||
PUBWEAK UART5_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
UART5_IRQHandler | |||
B UART5_IRQHandler | |||
PUBWEAK TIM6_DAC_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM6_DAC_IRQHandler | |||
B TIM6_DAC_IRQHandler | |||
PUBWEAK TIM7_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
TIM7_IRQHandler | |||
B TIM7_IRQHandler | |||
PUBWEAK DMA2_Stream0_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream0_IRQHandler | |||
B DMA2_Stream0_IRQHandler | |||
PUBWEAK DMA2_Stream1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream1_IRQHandler | |||
B DMA2_Stream1_IRQHandler | |||
PUBWEAK DMA2_Stream2_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream2_IRQHandler | |||
B DMA2_Stream2_IRQHandler | |||
PUBWEAK DMA2_Stream3_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream3_IRQHandler | |||
B DMA2_Stream3_IRQHandler | |||
PUBWEAK DMA2_Stream4_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream4_IRQHandler | |||
B DMA2_Stream4_IRQHandler | |||
PUBWEAK ETH_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
ETH_IRQHandler | |||
B ETH_IRQHandler | |||
PUBWEAK ETH_WKUP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
ETH_WKUP_IRQHandler | |||
B ETH_WKUP_IRQHandler | |||
PUBWEAK CAN2_TX_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN2_TX_IRQHandler | |||
B CAN2_TX_IRQHandler | |||
PUBWEAK CAN2_RX0_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN2_RX0_IRQHandler | |||
B CAN2_RX0_IRQHandler | |||
PUBWEAK CAN2_RX1_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN2_RX1_IRQHandler | |||
B CAN2_RX1_IRQHandler | |||
PUBWEAK CAN2_SCE_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CAN2_SCE_IRQHandler | |||
B CAN2_SCE_IRQHandler | |||
PUBWEAK OTG_FS_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_FS_IRQHandler | |||
B OTG_FS_IRQHandler | |||
PUBWEAK DMA2_Stream5_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream5_IRQHandler | |||
B DMA2_Stream5_IRQHandler | |||
PUBWEAK DMA2_Stream6_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream6_IRQHandler | |||
B DMA2_Stream6_IRQHandler | |||
PUBWEAK DMA2_Stream7_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DMA2_Stream7_IRQHandler | |||
B DMA2_Stream7_IRQHandler | |||
PUBWEAK USART6_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
USART6_IRQHandler | |||
B USART6_IRQHandler | |||
PUBWEAK I2C3_EV_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C3_EV_IRQHandler | |||
B I2C3_EV_IRQHandler | |||
PUBWEAK I2C3_ER_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
I2C3_ER_IRQHandler | |||
B I2C3_ER_IRQHandler | |||
PUBWEAK OTG_HS_EP1_OUT_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_HS_EP1_OUT_IRQHandler | |||
B OTG_HS_EP1_OUT_IRQHandler | |||
PUBWEAK OTG_HS_EP1_IN_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_HS_EP1_IN_IRQHandler | |||
B OTG_HS_EP1_IN_IRQHandler | |||
PUBWEAK OTG_HS_WKUP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_HS_WKUP_IRQHandler | |||
B OTG_HS_WKUP_IRQHandler | |||
PUBWEAK OTG_HS_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
OTG_HS_IRQHandler | |||
B OTG_HS_IRQHandler | |||
PUBWEAK DCMI_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
DCMI_IRQHandler | |||
B DCMI_IRQHandler | |||
PUBWEAK CRYP_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
CRYP_IRQHandler | |||
B CRYP_IRQHandler | |||
PUBWEAK HASH_RNG_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
HASH_RNG_IRQHandler | |||
B HASH_RNG_IRQHandler | |||
PUBWEAK FPU_IRQHandler | |||
SECTION .text:CODE:REORDER:NOROOT(1) | |||
FPU_IRQHandler | |||
B FPU_IRQHandler | |||
END | |||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@@ -0,0 +1,812 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project> | |||
<fileVersion>4</fileVersion> | |||
<fileChecksum>689384112</fileChecksum> | |||
<configuration> | |||
<name>Debug</name> | |||
<outputs> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_tmr.c</file> | |||
<file>$TOOLKIT_DIR$\inc\c\yvals.h</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_core.c</file> | |||
<file>$PROJ_DIR$\..\APP\main.c</file> | |||
<file>$PROJ_DIR$\..\APP\sys\sys.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_gpio.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_time.__cstat.et</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_mbox.c</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_exti.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_q.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\PORT\os_cpu.h</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_sem.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\PORT\os_cpu_a.asm</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_iwdg.h</file> | |||
<file>$PROJ_DIR$\..\UCOS\CONFIG\os_cfg.h</file> | |||
<file>$PROJ_DIR$\..\APP\system_stm32f4xx.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_time.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_mem.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\PORT\os_cpu_c.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_mutex.c</file> | |||
<file>$PROJ_DIR$\..\APP\sys\sys.c</file> | |||
<file>$PROJ_DIR$\..\APP\TIMER\timer.c</file> | |||
<file>$PROJ_DIR$\..\APP\stm32f4xx_it.c</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_gpio.c</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_syscfg.c</file> | |||
<file>$PROJ_DIR$\startup_stm32f40_41xxx.s</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\misc.c</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_rcc.c</file> | |||
<file>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_tim.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_flag.c</file> | |||
<file>$PROJ_DIR$\..\UCOS\CONFIG\includes.h</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\os_task.c</file> | |||
<file>$PROJ_DIR$\..\APP\delay\delay.c</file> | |||
<file>$PROJ_DIR$\..\APP\EXTI\exti.c</file> | |||
<file>$PROJ_DIR$\..\APP\LED\led.c</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\timer.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\timer.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mbox.xcl</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_flash.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mem.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_sem.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\sys.__cstat.et</file> | |||
<file>$TOOLKIT_DIR$\inc\c\stdint.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\main.o</file> | |||
<file>$PROJ_DIR$\..\APP\system_stm32f4xx.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_q.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mutex.o</file> | |||
<file>$PROJ_DIR$\..\APP\stm32f4xx_conf.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dbgmcu.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_tim.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_flag.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_cpu_a.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_time.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_cpu_c.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\startup_stm32f40_41xxx.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_core.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mbox.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\system_stm32f4xx.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\sys.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_it.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\main.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\system_stm32f4xx.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_cpu_c.__cstat.et</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_adc.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\iccarm_builtin.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_pwr.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_tim.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_tmr.__cstat.et</file> | |||
<file>$PROJ_DIR$\..\CMSIS\core_cm4_simd.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rcc.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_cpu_c.o</file> | |||
<file>$TOOLKIT_DIR$\inc\c\ycheck.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_task.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\sys.xcl</file> | |||
<file>$TOOLKIT_DIR$\inc\c\cmsis_iar.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\DLib_Product.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\misc.xcl</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dma.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.o</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_crc.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\DLib_Defaults.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_exti.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_flag.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_core.__cstat.et</file> | |||
<file>$PROJ_DIR$\..\APP\EXTI\exti.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_i2c.h</file> | |||
<file>$PROJ_DIR$\..\CMSIS\core_cmInstr.h</file> | |||
<file>$PROJ_DIR$\..\CMSIS\core_cm4.h</file> | |||
<file>$PROJ_DIR$\..\CMSIS\core_cmFunc.h</file> | |||
<file>$PROJ_DIR$\..\APP\stm32f4xx.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_it.xcl</file> | |||
<file>$TOOLKIT_DIR$\inc\c\DLib_Config_Full.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mutex.__cstat.et</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_wwdg.h</file> | |||
<file>$TOOLKIT_DIR$\lib\shb_l.a</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_tim.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Exe\task01.hex</file> | |||
<file>$TOOLKIT_DIR$\lib\dl7M_tlf.a</file> | |||
<file>$PROJ_DIR$\..\APP\LED\led.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\misc.o</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_usart.h</file> | |||
<file>$PROJ_DIR$\..\APP\TIMER\timer.h</file> | |||
<file>$TOOLKIT_DIR$\lib\rt7M_tl.a</file> | |||
<file>$PROJ_DIR$\..\APP\main.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_exti.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\main.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\led.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_exti.__cstat.et</file> | |||
<file>$TOOLKIT_DIR$\inc\c\DLib_Product_string.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\system_stm32f4xx.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\delay.__cstat.et</file> | |||
<file>$TOOLKIT_DIR$\lib\m7M_tls.a</file> | |||
<file>$TOOLKIT_DIR$\config\linker\ST\stm32f407xG.icf</file> | |||
<file>$PROJ_DIR$\..\UCOS\CORE\ucos_ii.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_hash.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\timer.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_exti.xcl</file> | |||
<file>$PROJ_DIR$\Debug\List\task01.map</file> | |||
<file>$PROJ_DIR$\Debug\Obj\misc.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\stm32f4xx_it.__cstat.et</file> | |||
<file>$PROJ_DIR$\Debug\Obj\exti.__cstat.et</file> | |||
<file>$TOOLKIT_DIR$\inc\c\stdarg.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\stdlib.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dac.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\led.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_task.xcl</file> | |||
<file>$TOOLKIT_DIR$\inc\c\string.h</file> | |||
<file>$PROJ_DIR$\..\APP\stm32f4xx_it.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_fsmc.h</file> | |||
<file>$PROJ_DIR$\..\APP\delay\delay.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_core.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_sem.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\exti.xcl</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_sdio.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\stdio.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\ctype.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\delay.xcl</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_syscfg.h</file> | |||
<file>$TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_can.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\task01.pbd</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rtc.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\led.o</file> | |||
<file>$TOOLKIT_DIR$\inc\c\ysizet.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_spi.h</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_cryp.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_sem.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mbox.o</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dcmi.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_q.o</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rng.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\exti.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_time.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Exe\task01.out</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\stm32f4xx_tim.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_q.xcl</file> | |||
<file>$PROJ_DIR$\..\DRIVER\inc\misc.h</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_tmr.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mutex.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_tmr.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\delay.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_task.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mem.o</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_mem.xcl</file> | |||
<file>$PROJ_DIR$\Debug\Obj\os_flag.xcl</file> | |||
</outputs> | |||
<file> | |||
<name>[ROOT_NODE]</name> | |||
<outputs> | |||
<tool> | |||
<name>ILINK</name> | |||
<file> 161 125</file> | |||
</tool> | |||
</outputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_tmr.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 165</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 71</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 167</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_core.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 59</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 88</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 138</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\main.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 44</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 110</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 64</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 108 30 142 75 1 85 96 80 151 134 114 143 130 146 129 119 14 10 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136 4 137 103 89 106</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_mbox.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 155</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 60</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 38</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_exti.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 109</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 113</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 124</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 86 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_q.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 157</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 47</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 163</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_sem.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 139</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 41</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 154</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\PORT\os_cpu_a.asm</name> | |||
<outputs> | |||
<tool> | |||
<name>AARM</name> | |||
<file> 54</file> | |||
</tool> | |||
</outputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\system_stm32f4xx.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 61</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 115</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 65</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_time.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 55</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 6</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 160</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_mem.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 170</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 40</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 171</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\PORT\os_cpu_c.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 74</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 66</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 57</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_mutex.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 48</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 97</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 166</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\sys\sys.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 62</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 42</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 78</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 4 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\TIMER\timer.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 37</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 122</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 36</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 106 4 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136 103</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\stm32f4xx_it.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 63</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 127</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 95</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 135 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136 119 30 142 151 134 114 143 130 146 129 10 14</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_gpio.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 123</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 51</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 121</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 5 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_syscfg.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 83</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 56</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 46</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 145 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\startup_stm32f40_41xxx.s</name> | |||
<outputs> | |||
<tool> | |||
<name>AARM</name> | |||
<file> 58</file> | |||
</tool> | |||
</outputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\misc.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 104</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 126</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 81</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 164 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_rcc.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 77</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 35</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 111</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 73 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\DRIVER\src\stm32f4xx_tim.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 70</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 52</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 100</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 162 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_flag.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 53</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 87</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 172</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\UCOS\CORE\os_task.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 169</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 76</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 133</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 119 30 142 75 1 85 96 80 151 134 114 143 130 146 129 10 14 94 92 43 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\delay\delay.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 168</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 116</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 144</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 137 4 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136 30 142 151 134 114 143 130 146 129 119 14 10</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\EXTI\exti.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 159</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 128</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 140</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 89 4 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136 137 103 30 142 151 134 114 143 130 146 129 119 14 10</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\..\APP\LED\led.c</name> | |||
<outputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 150</file> | |||
</tool> | |||
<tool> | |||
<name>__cstat</name> | |||
<file> 112</file> | |||
</tool> | |||
<tool> | |||
<name>BICOMP</name> | |||
<file> 132</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ICCARM</name> | |||
<file> 103 4 94 92 43 75 1 85 96 80 91 79 68 93 72 45 49 67 84 50 82 86 39 5 90 13 69 73 149 141 152 145 162 105 98 164 153 120 158 147 131 156 136</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
<file> | |||
<name>$PROJ_DIR$\Debug\Exe\task01.out</name> | |||
<outputs> | |||
<tool> | |||
<name>OBJCOPY</name> | |||
<file> 101</file> | |||
</tool> | |||
<tool> | |||
<name>ILINK</name> | |||
<file> 125</file> | |||
</tool> | |||
</outputs> | |||
<inputs> | |||
<tool> | |||
<name>ILINK</name> | |||
<file> 118 168 159 150 44 104 59 54 74 53 155 170 48 157 139 169 55 165 58 109 123 63 77 83 70 62 61 37 99 107 117 102</file> | |||
</tool> | |||
</inputs> | |||
</file> | |||
</configuration> | |||
<configuration> | |||
<name>Release</name> | |||
<outputs /> | |||
<forcedrebuild> | |||
<name>[MULTI_TOOL]</name> | |||
<tool>ILINK</tool> | |||
</forcedrebuild> | |||
</configuration> | |||
</project> |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<workspace> | |||
<project> | |||
<path>$WS_DIR$\task01.ewp</path> | |||
</project> | |||
<batchBuild /> | |||
</workspace> |
@@ -0,0 +1,56 @@ | |||
/* | |||
************************************************************************************************ | |||
主要的包含文件 | |||
文 件: INCLUDES.C ucos包含文件 | |||
作 者: Jean J. Labrosse | |||
************************************************************************************************ | |||
*/ | |||
#ifndef __INCLUDES_H__ | |||
#define __INCLUDES_H__ | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <ctype.h> | |||
#include <stdlib.h> | |||
#include <stdarg.h> | |||
#include "ucos_ii.h" | |||
#include "os_cpu.h" | |||
#include "os_cfg.h" | |||
#include <stm32f4xx.h> | |||
#endif | |||
@@ -0,0 +1,144 @@ | |||
/*UCOSIIÅäÖÃÎļþ | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* uC/OS-II Configuration File for V2.8x | |||
* | |||
* (c) Copyright 2005-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* | |||
* File : OS_CFG.H | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_CFG_H | |||
#define OS_CFG_H | |||
/* ---------------------- MISCELLANEOUS ----------------------- */ | |||
#define OS_APP_HOOKS_EN 0u /* Application-defined hooks are called from the uC/OS-II hooks */ | |||
#define OS_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */ | |||
#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */ | |||
#define OS_DEBUG_EN 0u /* Enable(1) debug variables */ | |||
#define OS_EVENT_MULTI_EN 0u /* Include code for OSEventPendMulti() */ | |||
#define OS_EVENT_NAME_EN 0u /* Enable names for Sem, Mutex, Mbox and Q */ | |||
#define OS_LOWEST_PRIO 63u /* Defines the lowest priority that can be assigned ... */ | |||
/* ... MUST NEVER be higher than 254! */ | |||
#define OS_MAX_EVENTS 10u /* Max. number of event control blocks in your application */ | |||
#define OS_MAX_FLAGS 5u /* Max. number of Event Flag Groups in your application */ | |||
#define OS_MAX_MEM_PART 1u /* Max. number of memory partitions */ | |||
#define OS_MAX_QS 5u /* Max. number of queue control blocks in your application */ | |||
#define OS_MAX_TASKS 60u /* Max. number of tasks in your application, MUST be >= 2 */ | |||
#define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */ | |||
#define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */ | |||
#define OS_TICKS_PER_SEC 200u /* Set the number of ticks in one second */ | |||
/* --------------------- TASK STACK SIZE ---------------------- */ | |||
#define OS_TASK_TMR_STK_SIZE 128u /* Timer task stack size (# of OS_STK wide entries) */ | |||
#define OS_TASK_STAT_STK_SIZE 128u /* Statistics task stack size (# of OS_STK wide entries) */ | |||
#define OS_TASK_IDLE_STK_SIZE 128u /* Idle task stack size (# of OS_STK wide entries) */ | |||
/* --------------------- TASK MANAGEMENT ---------------------- */ | |||
#define OS_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */ | |||
#define OS_TASK_CREATE_EN 1u /* Include code for OSTaskCreate() */ | |||
#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */ | |||
#define OS_TASK_DEL_EN 1u /* Include code for OSTaskDel() */ | |||
#define OS_TASK_NAME_EN 1u /* Enable task names */ | |||
#define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ | |||
#define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */ | |||
#define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */ | |||
#define OS_TASK_STAT_EN 1u /* Enable (1) or Disable(0) the statistics task */ | |||
#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */ | |||
#define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ | |||
#define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */ | |||
/* ----------------------- EVENT FLAGS ------------------------ */ | |||
#define OS_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ | |||
#define OS_FLAG_ACCEPT_EN 1u /* Include code for OSFlagAccept() */ | |||
#define OS_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */ | |||
#define OS_FLAG_NAME_EN 1u /* Enable names for event flag group */ | |||
#define OS_FLAG_QUERY_EN 1u /* Include code for OSFlagQuery() */ | |||
#define OS_FLAG_WAIT_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */ | |||
#define OS_FLAGS_NBITS 16u /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ | |||
/* -------------------- MESSAGE MAILBOXES --------------------- */ | |||
#define OS_MBOX_EN 1u /* Enable (1) or Disable (0) code generation for MAILBOXES */ | |||
#define OS_MBOX_ACCEPT_EN 1u /* Include code for OSMboxAccept() */ | |||
#define OS_MBOX_DEL_EN 1u /* Include code for OSMboxDel() */ | |||
#define OS_MBOX_PEND_ABORT_EN 1u /* Include code for OSMboxPendAbort() */ | |||
#define OS_MBOX_POST_EN 1u /* Include code for OSMboxPost() */ | |||
#define OS_MBOX_POST_OPT_EN 1u /* Include code for OSMboxPostOpt() */ | |||
#define OS_MBOX_QUERY_EN 1u /* Include code for OSMboxQuery() */ | |||
/* --------------------- MEMORY MANAGEMENT -------------------- */ | |||
#define OS_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ | |||
#define OS_MEM_NAME_EN 1u /* Enable memory partition names */ | |||
#define OS_MEM_QUERY_EN 1u /* Include code for OSMemQuery() */ | |||
/* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */ | |||
#define OS_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */ | |||
#define OS_MUTEX_ACCEPT_EN 1u /* Include code for OSMutexAccept() */ | |||
#define OS_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */ | |||
#define OS_MUTEX_QUERY_EN 1u /* Include code for OSMutexQuery() */ | |||
/* ---------------------- MESSAGE QUEUES ---------------------- */ | |||
#define OS_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */ | |||
#define OS_Q_ACCEPT_EN 1u /* Include code for OSQAccept() */ | |||
#define OS_Q_DEL_EN 1u /* Include code for OSQDel() */ | |||
#define OS_Q_FLUSH_EN 1u /* Include code for OSQFlush() */ | |||
#define OS_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */ | |||
#define OS_Q_POST_EN 1u /* Include code for OSQPost() */ | |||
#define OS_Q_POST_FRONT_EN 1u /* Include code for OSQPostFront() */ | |||
#define OS_Q_POST_OPT_EN 1u /* Include code for OSQPostOpt() */ | |||
#define OS_Q_QUERY_EN 1u /* Include code for OSQQuery() */ | |||
/* ------------------------ SEMAPHORES ------------------------ */ | |||
#define OS_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */ | |||
#define OS_SEM_ACCEPT_EN 1u /* Include code for OSSemAccept() */ | |||
#define OS_SEM_DEL_EN 1u /* Include code for OSSemDel() */ | |||
#define OS_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */ | |||
#define OS_SEM_QUERY_EN 1u /* Include code for OSSemQuery() */ | |||
#define OS_SEM_SET_EN 1u /* Include code for OSSemSet() */ | |||
/* --------------------- TIME MANAGEMENT ---------------------- */ | |||
#define OS_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */ | |||
#define OS_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */ | |||
#define OS_TIME_GET_SET_EN 1u /* Include code for OSTimeGet() and OSTimeSet() */ | |||
#define OS_TIME_TICK_HOOK_EN 1u /* Include code for OSTimeTickHook() */ | |||
/* --------------------- TIMER MANAGEMENT --------------------- */ | |||
#define OS_TMR_EN 0u /* Enable (1) or Disable (0) code generation for TIMERS */ | |||
#define OS_TMR_CFG_MAX 16u /* Maximum number of timers */ | |||
#define OS_TMR_CFG_NAME_EN 1u /* Determine timer names */ | |||
#define OS_TMR_CFG_WHEEL_SIZE 8u /* Size of timer wheel (#Spokes) */ | |||
#define OS_TMR_CFG_TICKS_PER_SEC 10u /* Rate at which timer management task runs (Hz) */ | |||
#endif | |||
@@ -0,0 +1,647 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* MESSAGE MAILBOX MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_MBOX.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
#if OS_MBOX_EN > 0u | |||
/* | |||
********************************************************************************************************* | |||
* ACCEPT MESSAGE FROM MAILBOX | |||
* | |||
* Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(), | |||
* OSMboxAccept() does not suspend the calling task if a message is not available. | |||
* | |||
* Arguments : pevent is a pointer to the event control block | |||
* | |||
* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared | |||
* so the next time OSMboxAccept() is called, the mailbox will be empty. | |||
* == (void *)0 if the mailbox is empty or, | |||
* if 'pevent' is a NULL pointer or, | |||
* if you didn't pass the proper event pointer. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_ACCEPT_EN > 0u | |||
void *OSMboxAccept (OS_EVENT *pevent) | |||
{ | |||
void *pmsg; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return ((void *)0); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
return ((void *)0); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pmsg = pevent->OSEventPtr; | |||
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ | |||
OS_EXIT_CRITICAL(); | |||
return (pmsg); /* Return the message received (or NULL) */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* CREATE A MESSAGE MAILBOX | |||
* | |||
* Description: This function creates a message mailbox if free event control blocks are available. | |||
* | |||
* Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If | |||
* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox | |||
* will be considered empty. | |||
* | |||
* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the | |||
* created mailbox | |||
* == (OS_EVENT *)0 if no event control blocks were available | |||
********************************************************************************************************* | |||
*/ | |||
OS_EVENT *OSMboxCreate (void *pmsg) | |||
{ | |||
OS_EVENT *pevent; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL_IEC61508 | |||
if (OSSafetyCriticalStartFlag == OS_TRUE) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pevent = OSEventFreeList; /* Get next free event control block */ | |||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ | |||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if (pevent != (OS_EVENT *)0) { | |||
pevent->OSEventType = OS_EVENT_TYPE_MBOX; | |||
pevent->OSEventCnt = 0u; | |||
pevent->OSEventPtr = pmsg; /* Deposit message in event control block */ | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
OS_EventWaitListInit(pevent); | |||
} | |||
return (pevent); /* Return pointer to event control block */ | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* DELETE A MAIBOX | |||
* | |||
* Description: This function deletes a mailbox and readies all tasks pending on the mailbox. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* mailbox. | |||
* | |||
* opt determines delete options as follows: | |||
* opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending | |||
* opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting. | |||
* In this case, all the tasks pending will be readied. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* OS_ERR_NONE The call was successful and the mailbox was deleted | |||
* OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR | |||
* OS_ERR_INVALID_OPT An invalid option was specified | |||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : pevent upon error | |||
* (OS_EVENT *)0 if the mailbox was successfully deleted. | |||
* | |||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of | |||
* the mailbox MUST check the return code of OSMboxPend(). | |||
* 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted! | |||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable | |||
* time is directly proportional to the number of tasks waiting on the mailbox. | |||
* 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in | |||
* applications where the mailbox is used for mutual exclusion because the resource(s) | |||
* will no longer be guarded by the mailbox. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_DEL_EN > 0u | |||
OS_EVENT *OSMboxDel (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
BOOLEAN tasks_waiting; | |||
OS_EVENT *pevent_return; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (pevent); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (pevent); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ | |||
return (pevent); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on mailbox */ | |||
tasks_waiting = OS_TRUE; /* Yes */ | |||
} else { | |||
tasks_waiting = OS_FALSE; /* No */ | |||
} | |||
switch (opt) { | |||
case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */ | |||
if (tasks_waiting == OS_FALSE) { | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_TASK_WAITING; | |||
pevent_return = pevent; | |||
} | |||
break; | |||
case OS_DEL_ALWAYS: /* Always delete the mailbox */ | |||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mailbox */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK); | |||
} | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
} | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ | |||
break; | |||
default: | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_INVALID_OPT; | |||
pevent_return = pevent; | |||
break; | |||
} | |||
return (pevent_return); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* PEND ON MAILBOX FOR A MESSAGE | |||
* | |||
* Description: This function waits for a message to be sent to a mailbox | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox | |||
* | |||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will | |||
* wait for a message to arrive at the mailbox up to the amount of time | |||
* specified by this argument. If you specify 0, however, your task will wait | |||
* forever at the specified mailbox or, until a message arrives. | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE The call was successful and your task received a | |||
* message. | |||
* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. | |||
* OS_ERR_PEND_ABORT The wait on the mailbox was aborted. | |||
* OS_ERR_EVENT_TYPE Invalid event type | |||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result | |||
* would lead to a suspension. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked | |||
* | |||
* Returns : != (void *)0 is a pointer to the message received | |||
* == (void *)0 if no message was received or, | |||
* if 'pevent' is a NULL pointer or, | |||
* if you didn't pass the proper pointer to the event control block. | |||
********************************************************************************************************* | |||
*/ | |||
/*$PAGE*/ | |||
void *OSMboxPend (OS_EVENT *pevent, | |||
INT32U timeout, | |||
INT8U *perr) | |||
{ | |||
void *pmsg; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return ((void *)0); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return ((void *)0); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ | |||
return ((void *)0); | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ | |||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ | |||
return ((void *)0); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pmsg = pevent->OSEventPtr; | |||
if (pmsg != (void *)0) { /* See if there is already a message */ | |||
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (pmsg); /* Return the message received (or NULL) */ | |||
} | |||
OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; | |||
OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ | |||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find next highest priority task ready to run */ | |||
OS_ENTER_CRITICAL(); | |||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ | |||
case OS_STAT_PEND_OK: | |||
pmsg = OSTCBCur->OSTCBMsg; | |||
*perr = OS_ERR_NONE; | |||
break; | |||
case OS_STAT_PEND_ABORT: | |||
pmsg = (void *)0; | |||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ | |||
break; | |||
case OS_STAT_PEND_TO: | |||
default: | |||
OS_EventTaskRemove(OSTCBCur, pevent); | |||
pmsg = (void *)0; | |||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ | |||
break; | |||
} | |||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ | |||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ | |||
#if (OS_EVENT_MULTI_EN > 0u) | |||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; | |||
#endif | |||
OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */ | |||
OS_EXIT_CRITICAL(); | |||
return (pmsg); /* Return received message */ | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ABORT WAITING ON A MESSAGE MAILBOX | |||
* | |||
* Description: This function aborts & readies any tasks currently waiting on a mailbox. This function | |||
* should be used to fault-abort the wait on the mailbox, rather than to normally signal | |||
* the mailbox via OSMboxPost() or OSMboxPostOpt(). | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox. | |||
* | |||
* opt determines the type of ABORT performed: | |||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the | |||
* mailbox | |||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the | |||
* mailbox | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE No tasks were waiting on the mailbox. | |||
* OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied | |||
* and informed of the aborted wait; check return value | |||
* for the number of tasks whose wait on the mailbox | |||
* was aborted. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : == 0 if no tasks were waiting on the mailbox, or upon error. | |||
* > 0 if one or more tasks waiting on the mailbox are now readied and informed. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_PEND_ABORT_EN > 0u | |||
INT8U OSMboxPendAbort (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
INT8U nbr_tasks; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (0u); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (0u); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on mailbox? */ | |||
nbr_tasks = 0u; | |||
switch (opt) { | |||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ | |||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on mailbox */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
} | |||
break; | |||
case OS_PEND_OPT_NONE: | |||
default: /* No, ready HPT waiting on mailbox */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
break; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find HPT ready to run */ | |||
*perr = OS_ERR_PEND_ABORT; | |||
return (nbr_tasks); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (0u); /* No tasks waiting on mailbox */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST MESSAGE TO A MAILBOX | |||
* | |||
* Description: This function sends a message to a mailbox | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox | |||
* | |||
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one | |||
* message at a time and thus, the message MUST be consumed before you | |||
* are allowed to send another one. | |||
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer | |||
* | |||
* Note(s) : 1) HPT means Highest Priority Task | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_POST_EN > 0u | |||
INT8U OSMboxPost (OS_EVENT *pevent, | |||
void *pmsg) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ | |||
return (OS_ERR_POST_NULL_PTR); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on mailbox */ | |||
/* Ready HPT waiting on event */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
return (OS_ERR_NONE); | |||
} | |||
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_MBOX_FULL); | |||
} | |||
pevent->OSEventPtr = pmsg; /* Place message in mailbox */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST MESSAGE TO A MAILBOX | |||
* | |||
* Description: This function sends a message to a mailbox | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox | |||
* | |||
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer. | |||
* | |||
* opt determines the type of POST performed: | |||
* OS_POST_OPT_NONE POST to a single waiting task | |||
* (Identical to OSMboxPost()) | |||
* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox | |||
* | |||
* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one | |||
* message at a time and thus, the message MUST be consumed before you | |||
* are allowed to send another one. | |||
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer | |||
* | |||
* Note(s) : 1) HPT means Highest Priority Task | |||
* | |||
* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the | |||
* interrupt disable time is proportional to the number of tasks waiting on the mailbox. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_POST_OPT_EN > 0u | |||
INT8U OSMboxPostOpt (OS_EVENT *pevent, | |||
void *pmsg, | |||
INT8U opt) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ | |||
return (OS_ERR_POST_NULL_PTR); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on mailbox */ | |||
if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */ | |||
while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on mailbox */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); | |||
} | |||
} else { /* No, Post to HPT waiting on mbox */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */ | |||
OS_Sched(); /* Find HPT ready to run */ | |||
} | |||
return (OS_ERR_NONE); | |||
} | |||
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_MBOX_FULL); | |||
} | |||
pevent->OSEventPtr = pmsg; /* Place message in mailbox */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUERY A MESSAGE MAILBOX | |||
* | |||
* Description: This function obtains information about a message mailbox. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox | |||
* | |||
* p_mbox_data is a pointer to a structure that will contain information about the message | |||
* mailbox. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MBOX_QUERY_EN > 0u | |||
INT8U OSMboxQuery (OS_EVENT *pevent, | |||
OS_MBOX_DATA *p_mbox_data) | |||
{ | |||
INT8U i; | |||
OS_PRIO *psrc; | |||
OS_PRIO *pdest; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (p_mbox_data == (OS_MBOX_DATA *)0) { /* Validate 'p_mbox_data' */ | |||
return (OS_ERR_PDATA_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
p_mbox_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ | |||
psrc = &pevent->OSEventTbl[0]; | |||
pdest = &p_mbox_data->OSEventTbl[0]; | |||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) { | |||
*pdest++ = *psrc++; | |||
} | |||
p_mbox_data->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif /* OS_MBOX_QUERY_EN */ | |||
#endif /* OS_MBOX_EN */ | |||
@@ -0,0 +1,456 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* MEMORY MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_MEM.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) | |||
/* | |||
********************************************************************************************************* | |||
* CREATE A MEMORY PARTITION | |||
* | |||
* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II. | |||
* | |||
* Arguments : addr is the starting address of the memory partition | |||
* | |||
* nblks is the number of memory blocks to create from the partition. | |||
* | |||
* blksize is the size (in bytes) of each block in the memory partition. | |||
* | |||
* perr is a pointer to a variable containing an error message which will be set by | |||
* this function to either: | |||
* | |||
* OS_ERR_NONE if the memory partition has been created correctly. | |||
* OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory | |||
* storage of the partition or, the block does not align | |||
* on a pointer boundary | |||
* OS_ERR_MEM_INVALID_PART no free partitions available | |||
* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2) | |||
* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size | |||
* - must be greater than the size of a pointer | |||
* - must be able to hold an integral number of pointers | |||
* Returns : != (OS_MEM *)0 is the partition was created | |||
* == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no | |||
* free partition is available. | |||
********************************************************************************************************* | |||
*/ | |||
OS_MEM *OSMemCreate (void *addr, | |||
INT32U nblks, | |||
INT32U blksize, | |||
INT8U *perr) | |||
{ | |||
OS_MEM *pmem; | |||
INT8U *pblk; | |||
void **plink; | |||
INT32U loops; | |||
INT32U i; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL_IEC61508 | |||
if (OSSafetyCriticalStartFlag == OS_TRUE) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/ | |||
*perr = OS_ERR_MEM_INVALID_ADDR; | |||
return ((OS_MEM *)0); | |||
} | |||
if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){ /* Must be pointer size aligned */ | |||
*perr = OS_ERR_MEM_INVALID_ADDR; | |||
return ((OS_MEM *)0); | |||
} | |||
if (nblks < 2u) { /* Must have at least 2 blocks per partition */ | |||
*perr = OS_ERR_MEM_INVALID_BLKS; | |||
return ((OS_MEM *)0); | |||
} | |||
if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */ | |||
*perr = OS_ERR_MEM_INVALID_SIZE; | |||
return ((OS_MEM *)0); | |||
} | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
pmem = OSMemFreeList; /* Get next free memory partition */ | |||
if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */ | |||
OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */ | |||
*perr = OS_ERR_MEM_INVALID_PART; | |||
return ((OS_MEM *)0); | |||
} | |||
plink = (void **)addr; /* Create linked list of free memory blocks */ | |||
pblk = (INT8U *)addr; | |||
loops = nblks - 1u; | |||
for (i = 0u; i < loops; i++) { | |||
pblk += blksize; /* Point to the FOLLOWING block */ | |||
*plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */ | |||
plink = (void **)pblk; /* Position to NEXT block */ | |||
} | |||
*plink = (void *)0; /* Last memory block points to NULL */ | |||
pmem->OSMemAddr = addr; /* Store start address of memory partition */ | |||
pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */ | |||
pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */ | |||
pmem->OSMemNBlks = nblks; | |||
pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */ | |||
*perr = OS_ERR_NONE; | |||
return (pmem); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* GET A MEMORY BLOCK | |||
* | |||
* Description : Get a memory block from a partition | |||
* | |||
* Arguments : pmem is a pointer to the memory partition control block | |||
* | |||
* perr is a pointer to a variable containing an error message which will be set by this | |||
* function to either: | |||
* | |||
* OS_ERR_NONE if the memory partition has been created correctly. | |||
* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller | |||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' | |||
* | |||
* Returns : A pointer to a memory block if no error is detected | |||
* A pointer to NULL if an error is detected | |||
********************************************************************************************************* | |||
*/ | |||
void *OSMemGet (OS_MEM *pmem, | |||
INT8U *perr) | |||
{ | |||
void *pblk; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ | |||
*perr = OS_ERR_MEM_INVALID_PMEM; | |||
return ((void *)0); | |||
} | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
if (pmem->OSMemNFree > 0u) { /* See if there are any free memory blocks */ | |||
pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */ | |||
pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */ | |||
pmem->OSMemNFree--; /* One less memory block in this partition */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; /* No error */ | |||
return (pblk); /* Return memory block to caller */ | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */ | |||
return ((void *)0); /* Return NULL pointer to caller */ | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* GET THE NAME OF A MEMORY PARTITION | |||
* | |||
* Description: This function is used to obtain the name assigned to a memory partition. | |||
* | |||
* Arguments : pmem is a pointer to the memory partition | |||
* | |||
* pname is a pointer to a pointer to an ASCII string that will receive the name of the memory partition. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* | |||
* OS_ERR_NONE if the name was copied to 'pname' | |||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' | |||
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' | |||
* OS_ERR_NAME_GET_ISR You called this function from an ISR | |||
* | |||
* Returns : The length of the string or 0 if 'pmem' is a NULL pointer. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MEM_NAME_EN > 0u | |||
INT8U OSMemNameGet (OS_MEM *pmem, | |||
INT8U **pname, | |||
INT8U *perr) | |||
{ | |||
INT8U len; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ | |||
*perr = OS_ERR_MEM_INVALID_PMEM; | |||
return (0u); | |||
} | |||
if (pname == (INT8U **)0) { /* Is 'pname' a NULL pointer? */ | |||
*perr = OS_ERR_PNAME_NULL; | |||
return (0u); | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ | |||
*perr = OS_ERR_NAME_GET_ISR; | |||
return (0u); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
*pname = pmem->OSMemName; | |||
len = OS_StrLen(*pname); | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (len); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ASSIGN A NAME TO A MEMORY PARTITION | |||
* | |||
* Description: This function assigns a name to a memory partition. | |||
* | |||
* Arguments : pmem is a pointer to the memory partition | |||
* | |||
* pname is a pointer to an ASCII string that contains the name of the memory partition. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* | |||
* OS_ERR_NONE if the name was copied to 'pname' | |||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' | |||
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' | |||
* OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area | |||
* OS_ERR_NAME_SET_ISR if you called this function from an ISR | |||
* | |||
* Returns : None | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MEM_NAME_EN > 0u | |||
void OSMemNameSet (OS_MEM *pmem, | |||
INT8U *pname, | |||
INT8U *perr) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */ | |||
*perr = OS_ERR_MEM_INVALID_PMEM; | |||
return; | |||
} | |||
if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ | |||
*perr = OS_ERR_PNAME_NULL; | |||
return; | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ | |||
*perr = OS_ERR_NAME_SET_ISR; | |||
return; | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pmem->OSMemName = pname; | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* RELEASE A MEMORY BLOCK | |||
* | |||
* Description : Returns a memory block to a partition | |||
* | |||
* Arguments : pmem is a pointer to the memory partition control block | |||
* | |||
* pblk is a pointer to the memory block being released. | |||
* | |||
* Returns : OS_ERR_NONE if the memory block was inserted into the partition | |||
* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory | |||
* partition (You freed more blocks than you allocated!) | |||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' | |||
* OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release. | |||
********************************************************************************************************* | |||
*/ | |||
INT8U OSMemPut (OS_MEM *pmem, | |||
void *pblk) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ | |||
return (OS_ERR_MEM_INVALID_PMEM); | |||
} | |||
if (pblk == (void *)0) { /* Must release a valid block */ | |||
return (OS_ERR_MEM_INVALID_PBLK); | |||
} | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_MEM_FULL); | |||
} | |||
*(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */ | |||
pmem->OSMemFreeList = pblk; | |||
pmem->OSMemNFree++; /* One more memory block in this partition */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); /* Notify caller that memory block was released */ | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUERY MEMORY PARTITION | |||
* | |||
* Description : This function is used to determine the number of free memory blocks and the number of | |||
* used memory blocks from a memory partition. | |||
* | |||
* Arguments : pmem is a pointer to the memory partition control block | |||
* | |||
* p_mem_data is a pointer to a structure that will contain information about the memory | |||
* partition. | |||
* | |||
* Returns : OS_ERR_NONE if no errors were found. | |||
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem' | |||
* OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MEM_QUERY_EN > 0u | |||
INT8U OSMemQuery (OS_MEM *pmem, | |||
OS_MEM_DATA *p_mem_data) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */ | |||
return (OS_ERR_MEM_INVALID_PMEM); | |||
} | |||
if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */ | |||
return (OS_ERR_MEM_INVALID_PDATA); | |||
} | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
p_mem_data->OSAddr = pmem->OSMemAddr; | |||
p_mem_data->OSFreeList = pmem->OSMemFreeList; | |||
p_mem_data->OSBlkSize = pmem->OSMemBlkSize; | |||
p_mem_data->OSNBlks = pmem->OSMemNBlks; | |||
p_mem_data->OSNFree = pmem->OSMemNFree; | |||
OS_EXIT_CRITICAL(); | |||
p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree; | |||
return (OS_ERR_NONE); | |||
} | |||
#endif /* OS_MEM_QUERY_EN */ | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* INITIALIZE MEMORY PARTITION MANAGER | |||
* | |||
* Description : This function is called by uC/OS-II to initialize the memory partition manager. Your | |||
* application MUST NOT call this function. | |||
* | |||
* Arguments : none | |||
* | |||
* Returns : none | |||
* | |||
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. | |||
********************************************************************************************************* | |||
*/ | |||
void OS_MemInit (void) | |||
{ | |||
#if OS_MAX_MEM_PART == 1u | |||
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ | |||
OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */ | |||
#if OS_MEM_NAME_EN > 0u | |||
OSMemFreeList->OSMemName = (INT8U *)"?"; /* Unknown name */ | |||
#endif | |||
#endif | |||
#if OS_MAX_MEM_PART >= 2u | |||
OS_MEM *pmem; | |||
INT16U i; | |||
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */ | |||
for (i = 0u; i < (OS_MAX_MEM_PART - 1u); i++) { /* Init. list of free memory partitions */ | |||
pmem = &OSMemTbl[i]; /* Point to memory control block (MCB) */ | |||
pmem->OSMemFreeList = (void *)&OSMemTbl[i + 1u]; /* Chain list of free partitions */ | |||
#if OS_MEM_NAME_EN > 0u | |||
pmem->OSMemName = (INT8U *)(void *)"?"; | |||
#endif | |||
} | |||
pmem = &OSMemTbl[i]; | |||
pmem->OSMemFreeList = (void *)0; /* Initialize last node */ | |||
#if OS_MEM_NAME_EN > 0u | |||
pmem->OSMemName = (INT8U *)(void *)"?"; | |||
#endif | |||
OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */ | |||
#endif | |||
} | |||
#endif /* OS_MEM_EN */ | |||
@@ -0,0 +1,735 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_MUTEX.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
#if OS_MUTEX_EN > 0u | |||
/* | |||
********************************************************************************************************* | |||
* LOCAL CONSTANTS | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_MUTEX_KEEP_LOWER_8 ((INT16U)0x00FFu) | |||
#define OS_MUTEX_KEEP_UPPER_8 ((INT16U)0xFF00u) | |||
#define OS_MUTEX_AVAILABLE ((INT16U)0x00FFu) | |||
/* | |||
********************************************************************************************************* | |||
* LOCAL CONSTANTS | |||
********************************************************************************************************* | |||
*/ | |||
static void OSMutex_RdyAtPrio(OS_TCB *ptcb, INT8U prio); | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ACCEPT MUTUAL EXCLUSION SEMAPHORE | |||
* | |||
* Description: This function checks the mutual exclusion semaphore to see if a resource is available. | |||
* Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is | |||
* not available or the event did not occur. | |||
* | |||
* Arguments : pevent is a pointer to the event control block | |||
* | |||
* perr is a pointer to an error code which will be returned to your application: | |||
* OS_ERR_NONE if the call was successful. | |||
* OS_ERR_EVENT_TYPE if 'pevent' is not a pointer to a mutex | |||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer | |||
* OS_ERR_PEND_ISR if you called this function from an ISR | |||
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is | |||
* HIGHER (i.e. a lower number) than the PIP. This error | |||
* indicates that you did not set the PIP higher (lower | |||
* number) than ALL the tasks that compete for the Mutex. | |||
* Unfortunately, this is something that could not be | |||
* detected when the Mutex is created because we don't know | |||
* what tasks will be using the Mutex. | |||
* | |||
* Returns : == OS_TRUE if the resource is available, the mutual exclusion semaphore is acquired | |||
* == OS_FALSE a) if the resource is not available | |||
* b) you didn't pass a pointer to a mutual exclusion semaphore | |||
* c) you called this function from an ISR | |||
* | |||
* Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are | |||
* intended to be used by tasks only. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MUTEX_ACCEPT_EN > 0u | |||
BOOLEAN OSMutexAccept (OS_EVENT *pevent, | |||
INT8U *perr) | |||
{ | |||
INT8U pip; /* Priority Inheritance Priority (PIP) */ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (OS_FALSE); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (OS_FALSE); | |||
} | |||
if (OSIntNesting > 0u) { /* Make sure it's not called from an ISR */ | |||
*perr = OS_ERR_PEND_ISR; | |||
return (OS_FALSE); | |||
} | |||
OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */ | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP from mutex */ | |||
if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { | |||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */ | |||
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */ | |||
pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */ | |||
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ | |||
OS_EXIT_CRITICAL(); /* ... than current task! */ | |||
*perr = OS_ERR_PIP_LOWER; | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
} | |||
return (OS_TRUE); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (OS_FALSE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* CREATE A MUTUAL EXCLUSION SEMAPHORE | |||
* | |||
* Description: This function creates a mutual exclusion semaphore. | |||
* | |||
* Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In | |||
* other words, when the semaphore is acquired and a higher priority task | |||
* attempts to obtain the semaphore then the priority of the task owning the | |||
* semaphore is raised to this priority. It is assumed that you will specify | |||
* a priority that is LOWER in value than ANY of the tasks competing for the | |||
* mutex. | |||
* | |||
* perr is a pointer to an error code which will be returned to your application: | |||
* OS_ERR_NONE if the call was successful. | |||
* OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR | |||
* OS_ERR_PRIO_EXIST if a task at the priority inheritance priority | |||
* already exist. | |||
* OS_ERR_PEVENT_NULL No more event control blocks available. | |||
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the | |||
* maximum allowed (i.e. > OS_LOWEST_PRIO) | |||
* | |||
* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the | |||
* created mutex. | |||
* == (void *)0 if an error is detected. | |||
* | |||
* Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number | |||
* of the task owning the mutex or 0xFF if no task owns the mutex. | |||
* | |||
* 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number | |||
* to use to reduce priority inversion. | |||
********************************************************************************************************* | |||
*/ | |||
OS_EVENT *OSMutexCreate (INT8U prio, | |||
INT8U *perr) | |||
{ | |||
OS_EVENT *pevent; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL_IEC61508 | |||
if (OSSafetyCriticalStartFlag == OS_TRUE) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */ | |||
*perr = OS_ERR_PRIO_INVALID; | |||
return ((OS_EVENT *)0); | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */ | |||
return ((OS_EVENT *)0); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */ | |||
OS_EXIT_CRITICAL(); /* Task already exist at priority ... */ | |||
*perr = OS_ERR_PRIO_EXIST; /* ... inheritance priority */ | |||
return ((OS_EVENT *)0); | |||
} | |||
OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */ | |||
pevent = OSEventFreeList; /* Get next free event control block */ | |||
if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */ | |||
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */ | |||
return (pevent); | |||
} | |||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */ | |||
OS_EXIT_CRITICAL(); | |||
pevent->OSEventType = OS_EVENT_TYPE_MUTEX; | |||
pevent->OSEventCnt = (INT16U)((INT16U)prio << 8u) | OS_MUTEX_AVAILABLE; /* Resource is avail. */ | |||
pevent->OSEventPtr = (void *)0; /* No task owning the mutex */ | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
OS_EventWaitListInit(pevent); | |||
*perr = OS_ERR_NONE; | |||
return (pevent); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* DELETE A MUTEX | |||
* | |||
* Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mutex. | |||
* | |||
* opt determines delete options as follows: | |||
* opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending | |||
* opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting. | |||
* In this case, all the tasks pending will be readied. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* OS_ERR_NONE The call was successful and the mutex was deleted | |||
* OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR | |||
* OS_ERR_INVALID_OPT An invalid option was specified | |||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : pevent upon error | |||
* (OS_EVENT *)0 if the mutex was successfully deleted. | |||
* | |||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of | |||
* the mutex MUST check the return code of OSMutexPend(). | |||
* | |||
* 2) This call can potentially disable interrupts for a long time. The interrupt disable | |||
* time is directly proportional to the number of tasks waiting on the mutex. | |||
* | |||
* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the | |||
* resource(s) will no longer be guarded by the mutex. | |||
* | |||
* 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there | |||
* is one) is ready-to-run and is thus NOT pending on another kernel object or | |||
* has delayed itself. In other words, if a task owns the mutex being deleted, | |||
* that task will be made ready-to-run at its original priority. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MUTEX_DEL_EN > 0u | |||
OS_EVENT *OSMutexDel (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
BOOLEAN tasks_waiting; | |||
OS_EVENT *pevent_return; | |||
INT8U pip; /* Priority inheritance priority */ | |||
INT8U prio; | |||
OS_TCB *ptcb; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (pevent); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (pevent); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ | |||
return (pevent); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on mutex */ | |||
tasks_waiting = OS_TRUE; /* Yes */ | |||
} else { | |||
tasks_waiting = OS_FALSE; /* No */ | |||
} | |||
switch (opt) { | |||
case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */ | |||
if (tasks_waiting == OS_FALSE) { | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); | |||
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_TASK_WAITING; | |||
pevent_return = pevent; | |||
} | |||
break; | |||
case OS_DEL_ALWAYS: /* ALWAYS DELETE THE MUTEX ---------------- */ | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP of mutex */ | |||
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original prio */ | |||
ptcb = (OS_TCB *)pevent->OSEventPtr; | |||
if (ptcb != (OS_TCB *)0) { /* See if any task owns the mutex */ | |||
if (ptcb->OSTCBPrio == pip) { /* See if original prio was changed */ | |||
OSMutex_RdyAtPrio(ptcb, prio); /* Yes, Restore the task's original prio */ | |||
} | |||
} | |||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mutex */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); | |||
} | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); | |||
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
} | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ | |||
break; | |||
default: | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_INVALID_OPT; | |||
pevent_return = pevent; | |||
break; | |||
} | |||
return (pevent_return); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* PEND ON MUTUAL EXCLUSION SEMAPHORE | |||
* | |||
* Description: This function waits for a mutual exclusion semaphore. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* mutex. | |||
* | |||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will | |||
* wait for the resource up to the amount of time specified by this argument. | |||
* If you specify 0, however, your task will wait forever at the specified | |||
* mutex or, until the resource becomes available. | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* OS_ERR_NONE The call was successful and your task owns the mutex | |||
* OS_ERR_TIMEOUT The mutex was not available within the specified 'timeout'. | |||
* OS_ERR_PEND_ABORT The wait on the mutex was aborted. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex | |||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer | |||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result | |||
* would lead to a suspension. | |||
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is | |||
* HIGHER (i.e. a lower number) than the PIP. This error | |||
* indicates that you did not set the PIP higher (lower | |||
* number) than ALL the tasks that compete for the Mutex. | |||
* Unfortunately, this is something that could not be | |||
* detected when the Mutex is created because we don't know | |||
* what tasks will be using the Mutex. | |||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked | |||
* | |||
* Returns : none | |||
* | |||
* Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex. | |||
* | |||
* 2) You MUST NOT change the priority of the task that owns the mutex | |||
********************************************************************************************************* | |||
*/ | |||
void OSMutexPend (OS_EVENT *pevent, | |||
INT32U timeout, | |||
INT8U *perr) | |||
{ | |||
INT8U pip; /* Priority Inheritance Priority (PIP) */ | |||
INT8U mprio; /* Mutex owner priority */ | |||
BOOLEAN rdy; /* Flag indicating task was ready */ | |||
OS_TCB *ptcb; | |||
OS_EVENT *pevent2; | |||
INT8U y; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return; | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return; | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ | |||
return; | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ | |||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ | |||
return; | |||
} | |||
/*$PAGE*/ | |||
OS_ENTER_CRITICAL(); | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get PIP from mutex */ | |||
/* Is Mutex available? */ | |||
if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) { | |||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */ | |||
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */ | |||
pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */ | |||
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */ | |||
OS_EXIT_CRITICAL(); /* ... than current task! */ | |||
*perr = OS_ERR_PIP_LOWER; | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
} | |||
return; | |||
} | |||
mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* No, Get priority of mutex owner */ | |||
ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */ | |||
if (ptcb->OSTCBPrio > pip) { /* Need to promote prio of owner?*/ | |||
if (mprio > OSTCBCur->OSTCBPrio) { | |||
y = ptcb->OSTCBY; | |||
if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0u) { /* See if mutex owner is ready */ | |||
OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Yes, Remove owner from Rdy ...*/ | |||
if (OSRdyTbl[y] == 0u) { /* ... list at current prio */ | |||
OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY; | |||
} | |||
rdy = OS_TRUE; | |||
} else { | |||
pevent2 = ptcb->OSTCBEventPtr; | |||
if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */ | |||
y = ptcb->OSTCBY; | |||
pevent2->OSEventTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; | |||
if (pevent2->OSEventTbl[y] == 0u) { | |||
pevent2->OSEventGrp &= (OS_PRIO)~ptcb->OSTCBBitY; | |||
} | |||
} | |||
rdy = OS_FALSE; /* No */ | |||
} | |||
ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */ | |||
#if OS_LOWEST_PRIO <= 63u | |||
ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3u); | |||
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07u); | |||
#else | |||
ptcb->OSTCBY = (INT8U)((INT8U)(ptcb->OSTCBPrio >> 4u) & 0xFFu); | |||
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x0Fu); | |||
#endif | |||
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY); | |||
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX); | |||
if (rdy == OS_TRUE) { /* If task was ready at owner's priority ...*/ | |||
OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */ | |||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; | |||
} else { | |||
pevent2 = ptcb->OSTCBEventPtr; | |||
if (pevent2 != (OS_EVENT *)0) { /* Add to event wait list */ | |||
pevent2->OSEventGrp |= ptcb->OSTCBBitY; | |||
pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; | |||
} | |||
} | |||
OSTCBPrioTbl[pip] = ptcb; | |||
} | |||
} | |||
OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend current task */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; | |||
OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's TCB */ | |||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find next highest priority task ready */ | |||
OS_ENTER_CRITICAL(); | |||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ | |||
case OS_STAT_PEND_OK: | |||
*perr = OS_ERR_NONE; | |||
break; | |||
case OS_STAT_PEND_ABORT: | |||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted getting mutex */ | |||
break; | |||
case OS_STAT_PEND_TO: | |||
default: | |||
OS_EventTaskRemove(OSTCBCur, pevent); | |||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get mutex within TO */ | |||
break; | |||
} | |||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ | |||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ | |||
#if (OS_EVENT_MULTI_EN > 0u) | |||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; | |||
#endif | |||
OS_EXIT_CRITICAL(); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST TO A MUTUAL EXCLUSION SEMAPHORE | |||
* | |||
* Description: This function signals a mutual exclusion semaphore | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* mutex. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the mutex was signaled. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex | |||
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer | |||
* OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes) | |||
* OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX. | |||
* OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is | |||
* HIGHER (i.e. a lower number) than the PIP. This error | |||
* indicates that you did not set the PIP higher (lower | |||
* number) than ALL the tasks that compete for the Mutex. | |||
* Unfortunately, this is something that could not be | |||
* detected when the Mutex is created because we don't know | |||
* what tasks will be using the Mutex. | |||
********************************************************************************************************* | |||
*/ | |||
INT8U OSMutexPost (OS_EVENT *pevent) | |||
{ | |||
INT8U pip; /* Priority inheritance priority */ | |||
INT8U prio; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */ | |||
} | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pip = (INT8U)(pevent->OSEventCnt >> 8u); /* Get priority inheritance priority of mutex */ | |||
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */ | |||
if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NOT_MUTEX_OWNER); | |||
} | |||
if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */ | |||
OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */ | |||
} | |||
OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */ | |||
if (pevent->OSEventGrp != 0u) { /* Any task waiting for the mutex? */ | |||
/* Yes, Make HPT waiting for mutex ready */ | |||
prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK); | |||
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */ | |||
pevent->OSEventCnt |= prio; | |||
pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */ | |||
if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */ | |||
OS_EXIT_CRITICAL(); /* ... than current task! */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
return (OS_ERR_PIP_LOWER); | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
return (OS_ERR_NONE); | |||
} | |||
} | |||
pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */ | |||
pevent->OSEventPtr = (void *)0; | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUERY A MUTUAL EXCLUSION SEMAPHORE | |||
* | |||
* Description: This function obtains information about a mutex | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired mutex | |||
* | |||
* p_mutex_data is a pointer to a structure that will contain information about the mutex | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_QUERY_ISR If you called this function from an ISR | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer | |||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_MUTEX_QUERY_EN > 0u | |||
INT8U OSMutexQuery (OS_EVENT *pevent, | |||
OS_MUTEX_DATA *p_mutex_data) | |||
{ | |||
INT8U i; | |||
OS_PRIO *psrc; | |||
OS_PRIO *pdest; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */ | |||
} | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */ | |||
return (OS_ERR_PDATA_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8u); | |||
p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); | |||
if (p_mutex_data->OSOwnerPrio == 0xFFu) { | |||
p_mutex_data->OSValue = OS_TRUE; | |||
} else { | |||
p_mutex_data->OSValue = OS_FALSE; | |||
} | |||
p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */ | |||
psrc = &pevent->OSEventTbl[0]; | |||
pdest = &p_mutex_data->OSEventTbl[0]; | |||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) { | |||
*pdest++ = *psrc++; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif /* OS_MUTEX_QUERY_EN */ | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY | |||
* | |||
* Description: This function makes a task ready at the specified priority | |||
* | |||
* Arguments : ptcb is a pointer to OS_TCB of the task to make ready | |||
* | |||
* prio is the desired priority | |||
* | |||
* Returns : none | |||
********************************************************************************************************* | |||
*/ | |||
static void OSMutex_RdyAtPrio (OS_TCB *ptcb, | |||
INT8U prio) | |||
{ | |||
INT8U y; | |||
y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */ | |||
OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; | |||
if (OSRdyTbl[y] == 0u) { | |||
OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY; | |||
} | |||
ptcb->OSTCBPrio = prio; | |||
OSPrioCur = prio; /* The current task is now at this priority */ | |||
#if OS_LOWEST_PRIO <= 63u | |||
ptcb->OSTCBY = (INT8U)((INT8U)(prio >> 3u) & 0x07u); | |||
ptcb->OSTCBX = (INT8U)(prio & 0x07u); | |||
#else | |||
ptcb->OSTCBY = (INT8U)((INT8U)(prio >> 4u) & 0x0Fu); | |||
ptcb->OSTCBX = (INT8U) (prio & 0x0Fu); | |||
#endif | |||
ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY); | |||
ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX); | |||
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */ | |||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; | |||
OSTCBPrioTbl[prio] = ptcb; | |||
} | |||
#endif /* OS_MUTEX_EN */ | |||
@@ -0,0 +1,893 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* MESSAGE QUEUE MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_Q.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u) | |||
/* | |||
********************************************************************************************************* | |||
* ACCEPT MESSAGE FROM QUEUE | |||
* | |||
* Description: This function checks the queue to see if a message is available. Unlike OSQPend(), | |||
* OSQAccept() does not suspend the calling task if a message is not available. | |||
* | |||
* Arguments : pevent is a pointer to the event control block | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE The call was successful and your task received a | |||
* message. | |||
* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_Q_EMPTY The queue did not contain any messages | |||
* | |||
* Returns : != (void *)0 is the message in the queue if one is available. The message is removed | |||
* from the so the next time OSQAccept() is called, the queue will contain | |||
* one less entry. | |||
* == (void *)0 if you received a NULL pointer message | |||
* if the queue is empty or, | |||
* if 'pevent' is a NULL pointer or, | |||
* if you passed an invalid event type | |||
* | |||
* Note(s) : As of V2.60, you can now pass NULL pointers through queues. Because of this, the argument | |||
* 'perr' has been added to the API to tell you about the outcome of the call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_ACCEPT_EN > 0u | |||
void *OSQAccept (OS_EVENT *pevent, | |||
INT8U *perr) | |||
{ | |||
void *pmsg; | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return ((void *)0); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return ((void *)0); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ | |||
if (pq->OSQEntries > 0u) { /* See if any messages in the queue */ | |||
pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ | |||
pq->OSQEntries--; /* Update the number of entries in the queue */ | |||
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ | |||
pq->OSQOut = pq->OSQStart; | |||
} | |||
*perr = OS_ERR_NONE; | |||
} else { | |||
*perr = OS_ERR_Q_EMPTY; | |||
pmsg = (void *)0; /* Queue is empty */ | |||
} | |||
OS_EXIT_CRITICAL(); | |||
return (pmsg); /* Return message received (or NULL) */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* CREATE A MESSAGE QUEUE | |||
* | |||
* Description: This function creates a message queue if free event control blocks are available. | |||
* | |||
* Arguments : start is a pointer to the base address of the message queue storage area. The | |||
* storage area MUST be declared as an array of pointers to 'void' as follows | |||
* | |||
* void *MessageStorage[size] | |||
* | |||
* size is the number of elements in the storage area | |||
* | |||
* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the | |||
* created queue | |||
* == (OS_EVENT *)0 if no event control blocks were available or an error was detected | |||
********************************************************************************************************* | |||
*/ | |||
OS_EVENT *OSQCreate (void **start, | |||
INT16U size) | |||
{ | |||
OS_EVENT *pevent; | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL_IEC61508 | |||
if (OSSafetyCriticalStartFlag == OS_TRUE) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pevent = OSEventFreeList; /* Get next free event control block */ | |||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ | |||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */ | |||
OS_ENTER_CRITICAL(); | |||
pq = OSQFreeList; /* Get a free queue control block */ | |||
if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */ | |||
OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/ | |||
OS_EXIT_CRITICAL(); | |||
pq->OSQStart = start; /* Initialize the queue */ | |||
pq->OSQEnd = &start[size]; | |||
pq->OSQIn = start; | |||
pq->OSQOut = start; | |||
pq->OSQSize = size; | |||
pq->OSQEntries = 0u; | |||
pevent->OSEventType = OS_EVENT_TYPE_Q; | |||
pevent->OSEventCnt = 0u; | |||
pevent->OSEventPtr = pq; | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
OS_EventWaitListInit(pevent); /* Initalize the wait list */ | |||
} else { | |||
pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */ | |||
OSEventFreeList = pevent; | |||
OS_EXIT_CRITICAL(); | |||
pevent = (OS_EVENT *)0; | |||
} | |||
} | |||
return (pevent); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* DELETE A MESSAGE QUEUE | |||
* | |||
* Description: This function deletes a message queue and readies all tasks pending on the queue. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* queue. | |||
* | |||
* opt determines delete options as follows: | |||
* opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending | |||
* opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting. | |||
* In this case, all the tasks pending will be readied. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* OS_ERR_NONE The call was successful and the queue was deleted | |||
* OS_ERR_DEL_ISR If you tried to delete the queue from an ISR | |||
* OS_ERR_INVALID_OPT An invalid option was specified | |||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the queue | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : pevent upon error | |||
* (OS_EVENT *)0 if the queue was successfully deleted. | |||
* | |||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of | |||
* the queue MUST check the return code of OSQPend(). | |||
* 2) OSQAccept() callers will not know that the intended queue has been deleted unless | |||
* they check 'pevent' to see that it's a NULL pointer. | |||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable | |||
* time is directly proportional to the number of tasks waiting on the queue. | |||
* 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in | |||
* applications where the queue is used for mutual exclusion because the resource(s) | |||
* will no longer be guarded by the queue. | |||
* 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc() | |||
* type call) then your application MUST release the memory storage by call the counterpart | |||
* call of the dynamic allocation scheme used. If the queue storage was created statically | |||
* then, the storage can be reused. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_DEL_EN > 0u | |||
OS_EVENT *OSQDel (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
BOOLEAN tasks_waiting; | |||
OS_EVENT *pevent_return; | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (pevent); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (pevent); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ | |||
return (pevent); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on queue */ | |||
tasks_waiting = OS_TRUE; /* Yes */ | |||
} else { | |||
tasks_waiting = OS_FALSE; /* No */ | |||
} | |||
switch (opt) { | |||
case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */ | |||
if (tasks_waiting == OS_FALSE) { | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ | |||
pq->OSQPtr = OSQFreeList; | |||
OSQFreeList = pq; | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_TASK_WAITING; | |||
pevent_return = pevent; | |||
} | |||
break; | |||
case OS_DEL_ALWAYS: /* Always delete the queue */ | |||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for queue */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_OK); | |||
} | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ | |||
pq->OSQPtr = OSQFreeList; | |||
OSQFreeList = pq; | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
} | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Queue has been deleted */ | |||
break; | |||
default: | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_INVALID_OPT; | |||
pevent_return = pevent; | |||
break; | |||
} | |||
return (pevent_return); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* FLUSH QUEUE | |||
* | |||
* Description : This function is used to flush the contents of the message queue. | |||
* | |||
* Arguments : none | |||
* | |||
* Returns : OS_ERR_NONE upon success | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* | |||
* WARNING : You should use this function with great care because, when to flush the queue, you LOOSE | |||
* the references to what the queue entries are pointing to and thus, you could cause | |||
* 'memory leaks'. In other words, the data you are pointing to that's being referenced | |||
* by the queue entries should, most likely, need to be de-allocated (i.e. freed). | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_FLUSH_EN > 0u | |||
INT8U OSQFlush (OS_EVENT *pevent) | |||
{ | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */ | |||
pq->OSQIn = pq->OSQStart; | |||
pq->OSQOut = pq->OSQStart; | |||
pq->OSQEntries = 0u; | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* PEND ON A QUEUE FOR A MESSAGE | |||
* | |||
* Description: This function waits for a message to be sent to a queue | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue | |||
* | |||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will | |||
* wait for a message to arrive at the queue up to the amount of time | |||
* specified by this argument. If you specify 0, however, your task will wait | |||
* forever at the specified queue or, until a message arrives. | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE The call was successful and your task received a | |||
* message. | |||
* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'. | |||
* OS_ERR_PEND_ABORT The wait on the queue was aborted. | |||
* OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result | |||
* would lead to a suspension. | |||
* OS_ERR_PEND_LOCKED If you called this function with the scheduler is locked | |||
* | |||
* Returns : != (void *)0 is a pointer to the message received | |||
* == (void *)0 if you received a NULL pointer message or, | |||
* if no message was received or, | |||
* if 'pevent' is a NULL pointer or, | |||
* if you didn't pass a pointer to a queue. | |||
* | |||
* Note(s) : As of V2.60, this function allows you to receive NULL pointer messages. | |||
********************************************************************************************************* | |||
*/ | |||
void *OSQPend (OS_EVENT *pevent, | |||
INT32U timeout, | |||
INT8U *perr) | |||
{ | |||
void *pmsg; | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return ((void *)0); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return ((void *)0); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ | |||
return ((void *)0); | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ | |||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ | |||
return ((void *)0); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ | |||
if (pq->OSQEntries > 0u) { /* See if any messages in the queue */ | |||
pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ | |||
pq->OSQEntries--; /* Update the number of entries in the queue */ | |||
if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ | |||
pq->OSQOut = pq->OSQStart; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (pmsg); /* Return message received */ | |||
} | |||
OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; | |||
OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */ | |||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find next highest priority task ready to run */ | |||
OS_ENTER_CRITICAL(); | |||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ | |||
case OS_STAT_PEND_OK: /* Extract message from TCB (Put there by QPost) */ | |||
pmsg = OSTCBCur->OSTCBMsg; | |||
*perr = OS_ERR_NONE; | |||
break; | |||
case OS_STAT_PEND_ABORT: | |||
pmsg = (void *)0; | |||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ | |||
break; | |||
case OS_STAT_PEND_TO: | |||
default: | |||
OS_EventTaskRemove(OSTCBCur, pevent); | |||
pmsg = (void *)0; | |||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ | |||
break; | |||
} | |||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ | |||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ | |||
#if (OS_EVENT_MULTI_EN > 0u) | |||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; | |||
#endif | |||
OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */ | |||
OS_EXIT_CRITICAL(); | |||
return (pmsg); /* Return received message */ | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ABORT WAITING ON A MESSAGE QUEUE | |||
* | |||
* Description: This function aborts & readies any tasks currently waiting on a queue. This function | |||
* should be used to fault-abort the wait on the queue, rather than to normally signal | |||
* the queue via OSQPost(), OSQPostFront() or OSQPostOpt(). | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue. | |||
* | |||
* opt determines the type of ABORT performed: | |||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the | |||
* queue | |||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the | |||
* queue | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE No tasks were waiting on the queue. | |||
* OS_ERR_PEND_ABORT At least one task waiting on the queue was readied | |||
* and informed of the aborted wait; check return value | |||
* for the number of tasks whose wait on the queue | |||
* was aborted. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : == 0 if no tasks were waiting on the queue, or upon error. | |||
* > 0 if one or more tasks waiting on the queue are now readied and informed. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_PEND_ABORT_EN > 0u | |||
INT8U OSQPendAbort (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
INT8U nbr_tasks; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (0u); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (0u); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on queue? */ | |||
nbr_tasks = 0u; | |||
switch (opt) { | |||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ | |||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on queue */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
} | |||
break; | |||
case OS_PEND_OPT_NONE: | |||
default: /* No, ready HPT waiting on queue */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
break; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find HPT ready to run */ | |||
*perr = OS_ERR_PEND_ABORT; | |||
return (nbr_tasks); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (0u); /* No tasks waiting on queue */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST MESSAGE TO A QUEUE | |||
* | |||
* Description: This function sends a message to a queue | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue | |||
* | |||
* pmsg is a pointer to the message to send. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* | |||
* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_POST_EN > 0u | |||
INT8U OSQPost (OS_EVENT *pevent, | |||
void *pmsg) | |||
{ | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on queue */ | |||
/* Ready highest priority task waiting on event */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
return (OS_ERR_NONE); | |||
} | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ | |||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_Q_FULL); | |||
} | |||
*pq->OSQIn++ = pmsg; /* Insert message into queue */ | |||
pq->OSQEntries++; /* Update the nbr of entries in the queue */ | |||
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ | |||
pq->OSQIn = pq->OSQStart; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST MESSAGE TO THE FRONT OF A QUEUE | |||
* | |||
* Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at | |||
* the front instead of the end of the queue. Using OSQPostFront() allows you to send | |||
* 'priority' messages. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue | |||
* | |||
* pmsg is a pointer to the message to send. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* | |||
* Note(s) : As of V2.60, this function allows you to send NULL pointer messages. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_POST_FRONT_EN > 0u | |||
INT8U OSQPostFront (OS_EVENT *pevent, | |||
void *pmsg) | |||
{ | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task pending on queue */ | |||
/* Ready highest priority task waiting on event */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
return (OS_ERR_NONE); | |||
} | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ | |||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_Q_FULL); | |||
} | |||
if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */ | |||
pq->OSQOut = pq->OSQEnd; | |||
} | |||
pq->OSQOut--; | |||
*pq->OSQOut = pmsg; /* Insert message into queue */ | |||
pq->OSQEntries++; /* Update the nbr of entries in the queue */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST MESSAGE TO A QUEUE | |||
* | |||
* Description: This function sends a message to a queue. This call has been added to reduce code size | |||
* since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the | |||
* capability to broadcast a message to ALL tasks waiting on the message queue. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue | |||
* | |||
* pmsg is a pointer to the message to send. | |||
* | |||
* opt determines the type of POST performed: | |||
* OS_POST_OPT_NONE POST to a single waiting task | |||
* (Identical to OSQPost()) | |||
* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue | |||
* OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront()) | |||
* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_Q_FULL If the queue cannot accept any more messages because it is full. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* | |||
* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the | |||
* interrupt disable time is proportional to the number of tasks waiting on the queue. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_POST_OPT_EN > 0u | |||
INT8U OSQPostOpt (OS_EVENT *pevent, | |||
void *pmsg, | |||
INT8U opt) | |||
{ | |||
OS_Q *pq; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0x00u) { /* See if any task pending on queue */ | |||
if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */ | |||
while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on queue */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); | |||
} | |||
} else { /* No, Post to HPT waiting on queue */ | |||
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
} | |||
return (OS_ERR_NONE); | |||
} | |||
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ | |||
if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_Q_FULL); | |||
} | |||
if ((opt & OS_POST_OPT_FRONT) != 0x00u) { /* Do we post to the FRONT of the queue? */ | |||
if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */ | |||
pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */ | |||
} | |||
pq->OSQOut--; | |||
*pq->OSQOut = pmsg; /* Insert message into queue */ | |||
} else { /* No, Post as FIFO */ | |||
*pq->OSQIn++ = pmsg; /* Insert message into queue */ | |||
if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ | |||
pq->OSQIn = pq->OSQStart; | |||
} | |||
} | |||
pq->OSQEntries++; /* Update the nbr of entries in the queue */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUERY A MESSAGE QUEUE | |||
* | |||
* Description: This function obtains information about a message queue. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired queue | |||
* | |||
* p_q_data is a pointer to a structure that will contain information about the message | |||
* queue. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer | |||
* OS_ERR_PDATA_NULL If 'p_q_data' is a NULL pointer | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_Q_QUERY_EN > 0u | |||
INT8U OSQQuery (OS_EVENT *pevent, | |||
OS_Q_DATA *p_q_data) | |||
{ | |||
OS_Q *pq; | |||
INT8U i; | |||
OS_PRIO *psrc; | |||
OS_PRIO *pdest; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (p_q_data == (OS_Q_DATA *)0) { /* Validate 'p_q_data' */ | |||
return (OS_ERR_PDATA_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
p_q_data->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */ | |||
psrc = &pevent->OSEventTbl[0]; | |||
pdest = &p_q_data->OSEventTbl[0]; | |||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) { | |||
*pdest++ = *psrc++; | |||
} | |||
pq = (OS_Q *)pevent->OSEventPtr; | |||
if (pq->OSQEntries > 0u) { | |||
p_q_data->OSMsg = *pq->OSQOut; /* Get next message to return if available */ | |||
} else { | |||
p_q_data->OSMsg = (void *)0; | |||
} | |||
p_q_data->OSNMsgs = pq->OSQEntries; | |||
p_q_data->OSQSize = pq->OSQSize; | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif /* OS_Q_QUERY_EN */ | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUEUE MODULE INITIALIZATION | |||
* | |||
* Description : This function is called by uC/OS-II to initialize the message queue module. Your | |||
* application MUST NOT call this function. | |||
* | |||
* Arguments : none | |||
* | |||
* Returns : none | |||
* | |||
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. | |||
********************************************************************************************************* | |||
*/ | |||
void OS_QInit (void) | |||
{ | |||
#if OS_MAX_QS == 1u | |||
OSQFreeList = &OSQTbl[0]; /* Only ONE queue! */ | |||
OSQFreeList->OSQPtr = (OS_Q *)0; | |||
#endif | |||
#if OS_MAX_QS >= 2u | |||
INT16U ix; | |||
INT16U ix_next; | |||
OS_Q *pq1; | |||
OS_Q *pq2; | |||
OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl)); /* Clear the queue table */ | |||
for (ix = 0u; ix < (OS_MAX_QS - 1u); ix++) { /* Init. list of free QUEUE control blocks */ | |||
ix_next = ix + 1u; | |||
pq1 = &OSQTbl[ix]; | |||
pq2 = &OSQTbl[ix_next]; | |||
pq1->OSQPtr = pq2; | |||
} | |||
pq1 = &OSQTbl[ix]; | |||
pq1->OSQPtr = (OS_Q *)0; | |||
OSQFreeList = &OSQTbl[0]; | |||
#endif | |||
} | |||
#endif /* OS_Q_EN */ | |||
@@ -0,0 +1,629 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* SEMAPHORE MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_SEM.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
#if OS_SEM_EN > 0u | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ACCEPT SEMAPHORE | |||
* | |||
* Description: This function checks the semaphore to see if a resource is available or, if an event | |||
* occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the | |||
* resource is not available or the event did not occur. | |||
* | |||
* Arguments : pevent is a pointer to the event control block | |||
* | |||
* Returns : > 0 if the resource is available or the event did not occur the semaphore is | |||
* decremented to obtain the resource. | |||
* == 0 if the resource is not available or the event did not occur or, | |||
* if 'pevent' is a NULL pointer or, | |||
* if you didn't pass a pointer to a semaphore | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_SEM_ACCEPT_EN > 0u | |||
INT16U OSSemAccept (OS_EVENT *pevent) | |||
{ | |||
INT16U cnt; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (0u); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
return (0u); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
cnt = pevent->OSEventCnt; | |||
if (cnt > 0u) { /* See if resource is available */ | |||
pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */ | |||
} | |||
OS_EXIT_CRITICAL(); | |||
return (cnt); /* Return semaphore count */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* CREATE A SEMAPHORE | |||
* | |||
* Description: This function creates a semaphore. | |||
* | |||
* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is | |||
* available (or no event has occurred). You initialize the semaphore to a | |||
* non-zero value to specify how many resources are available (e.g. if you have | |||
* 10 resources, you would initialize the semaphore to 10). | |||
* | |||
* Returns : != (void *)0 is a pointer to the event control block (OS_EVENT) associated with the | |||
* created semaphore | |||
* == (void *)0 if no event control blocks were available | |||
********************************************************************************************************* | |||
*/ | |||
OS_EVENT *OSSemCreate (INT16U cnt) | |||
{ | |||
OS_EVENT *pevent; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL_IEC61508 | |||
if (OSSafetyCriticalStartFlag == OS_TRUE) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */ | |||
} | |||
OS_ENTER_CRITICAL(); | |||
pevent = OSEventFreeList; /* Get next free event control block */ | |||
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */ | |||
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
if (pevent != (OS_EVENT *)0) { /* Get an event control block */ | |||
pevent->OSEventType = OS_EVENT_TYPE_SEM; | |||
pevent->OSEventCnt = cnt; /* Set semaphore value */ | |||
pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */ | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */ | |||
} | |||
return (pevent); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* DELETE A SEMAPHORE | |||
* | |||
* Description: This function deletes a semaphore and readies all tasks pending on the semaphore. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* semaphore. | |||
* | |||
* opt determines delete options as follows: | |||
* opt == OS_DEL_NO_PEND Delete semaphore ONLY if no task pending | |||
* opt == OS_DEL_ALWAYS Deletes the semaphore even if tasks are waiting. | |||
* In this case, all the tasks pending will be readied. | |||
* | |||
* perr is a pointer to an error code that can contain one of the following values: | |||
* OS_ERR_NONE The call was successful and the semaphore was deleted | |||
* OS_ERR_DEL_ISR If you attempted to delete the semaphore from an ISR | |||
* OS_ERR_INVALID_OPT An invalid option was specified | |||
* OS_ERR_TASK_WAITING One or more tasks were waiting on the semaphore | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : pevent upon error | |||
* (OS_EVENT *)0 if the semaphore was successfully deleted. | |||
* | |||
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of | |||
* the semaphore MUST check the return code of OSSemPend(). | |||
* 2) OSSemAccept() callers will not know that the intended semaphore has been deleted unless | |||
* they check 'pevent' to see that it's a NULL pointer. | |||
* 3) This call can potentially disable interrupts for a long time. The interrupt disable | |||
* time is directly proportional to the number of tasks waiting on the semaphore. | |||
* 4) Because ALL tasks pending on the semaphore will be readied, you MUST be careful in | |||
* applications where the semaphore is used for mutual exclusion because the resource(s) | |||
* will no longer be guarded by the semaphore. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_SEM_DEL_EN > 0u | |||
OS_EVENT *OSSemDel (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
BOOLEAN tasks_waiting; | |||
OS_EVENT *pevent_return; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (pevent); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (pevent); | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ | |||
return (pevent); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on semaphore */ | |||
tasks_waiting = OS_TRUE; /* Yes */ | |||
} else { | |||
tasks_waiting = OS_FALSE; /* No */ | |||
} | |||
switch (opt) { | |||
case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ | |||
if (tasks_waiting == OS_FALSE) { | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ | |||
} else { | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_TASK_WAITING; | |||
pevent_return = pevent; | |||
} | |||
break; | |||
case OS_DEL_ALWAYS: /* Always delete the semaphore */ | |||
while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for semaphore */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); | |||
} | |||
#if OS_EVENT_NAME_EN > 0u | |||
pevent->OSEventName = (INT8U *)(void *)"?"; | |||
#endif | |||
pevent->OSEventType = OS_EVENT_TYPE_UNUSED; | |||
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ | |||
pevent->OSEventCnt = 0u; | |||
OSEventFreeList = pevent; /* Get next free event control block */ | |||
OS_EXIT_CRITICAL(); | |||
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ | |||
OS_Sched(); /* Find highest priority task ready to run */ | |||
} | |||
*perr = OS_ERR_NONE; | |||
pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ | |||
break; | |||
default: | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_INVALID_OPT; | |||
pevent_return = pevent; | |||
break; | |||
} | |||
return (pevent_return); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* PEND ON SEMAPHORE | |||
* | |||
* Description: This function waits for a semaphore. | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* semaphore. | |||
* | |||
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will | |||
* wait for the resource up to the amount of time specified by this argument. | |||
* If you specify 0, however, your task will wait forever at the specified | |||
* semaphore or, until the resource becomes available (or the event occurs). | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE The call was successful and your task owns the resource | |||
* or, the event you are waiting for occurred. | |||
* OS_ERR_TIMEOUT The semaphore was not received within the specified | |||
* 'timeout'. | |||
* OS_ERR_PEND_ABORT The wait on the semaphore was aborted. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. | |||
* OS_ERR_PEND_ISR If you called this function from an ISR and the result | |||
* would lead to a suspension. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked | |||
* | |||
* Returns : none | |||
********************************************************************************************************* | |||
*/ | |||
/*$PAGE*/ | |||
void OSSemPend (OS_EVENT *pevent, | |||
INT32U timeout, | |||
INT8U *perr) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return; | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return; | |||
} | |||
if (OSIntNesting > 0u) { /* See if called from ISR ... */ | |||
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ | |||
return; | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ | |||
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ | |||
return; | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventCnt > 0u) { /* If sem. is positive, resource available ... */ | |||
pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return; | |||
} | |||
/* Otherwise, must wait until event occurs */ | |||
OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; | |||
OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ | |||
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find next highest priority task ready */ | |||
OS_ENTER_CRITICAL(); | |||
switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ | |||
case OS_STAT_PEND_OK: | |||
*perr = OS_ERR_NONE; | |||
break; | |||
case OS_STAT_PEND_ABORT: | |||
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ | |||
break; | |||
case OS_STAT_PEND_TO: | |||
default: | |||
OS_EventTaskRemove(OSTCBCur, pevent); | |||
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ | |||
break; | |||
} | |||
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ | |||
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ | |||
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ | |||
#if (OS_EVENT_MULTI_EN > 0u) | |||
OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; | |||
#endif | |||
OS_EXIT_CRITICAL(); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* ABORT WAITING ON A SEMAPHORE | |||
* | |||
* Description: This function aborts & readies any tasks currently waiting on a semaphore. This function | |||
* should be used to fault-abort the wait on the semaphore, rather than to normally signal | |||
* the semaphore via OSSemPost(). | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* semaphore. | |||
* | |||
* opt determines the type of ABORT performed: | |||
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the | |||
* semaphore | |||
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the | |||
* semaphore | |||
* | |||
* perr is a pointer to where an error message will be deposited. Possible error | |||
* messages are: | |||
* | |||
* OS_ERR_NONE No tasks were waiting on the semaphore. | |||
* OS_ERR_PEND_ABORT At least one task waiting on the semaphore was readied | |||
* and informed of the aborted wait; check return value | |||
* for the number of tasks whose wait on the semaphore | |||
* was aborted. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* | |||
* Returns : == 0 if no tasks were waiting on the semaphore, or upon error. | |||
* > 0 if one or more tasks waiting on the semaphore are now readied and informed. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_SEM_PEND_ABORT_EN > 0u | |||
INT8U OSSemPendAbort (OS_EVENT *pevent, | |||
INT8U opt, | |||
INT8U *perr) | |||
{ | |||
INT8U nbr_tasks; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return (0u); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return (0u); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting on semaphore? */ | |||
nbr_tasks = 0u; | |||
switch (opt) { | |||
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ | |||
while (pevent->OSEventGrp != 0u) { /* Yes, ready ALL tasks waiting on semaphore */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
} | |||
break; | |||
case OS_PEND_OPT_NONE: | |||
default: /* No, ready HPT waiting on semaphore */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); | |||
nbr_tasks++; | |||
break; | |||
} | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find HPT ready to run */ | |||
*perr = OS_ERR_PEND_ABORT; | |||
return (nbr_tasks); | |||
} | |||
OS_EXIT_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
return (0u); /* No tasks waiting on semaphore */ | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* POST TO A SEMAPHORE | |||
* | |||
* Description: This function signals a semaphore | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* semaphore. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the semaphore was signaled. | |||
* OS_ERR_SEM_OVF If the semaphore count exceeded its limit. In other words, you have | |||
* signalled the semaphore more often than you waited on it with either | |||
* OSSemAccept() or OSSemPend(). | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
********************************************************************************************************* | |||
*/ | |||
INT8U OSSemPost (OS_EVENT *pevent) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
if (pevent->OSEventGrp != 0u) { /* See if any task waiting for semaphore */ | |||
/* Ready HPT waiting on event */ | |||
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find HPT ready to run */ | |||
return (OS_ERR_NONE); | |||
} | |||
if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */ | |||
pevent->OSEventCnt++; /* Increment semaphore count to register event */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ | |||
return (OS_ERR_SEM_OVF); | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* QUERY A SEMAPHORE | |||
* | |||
* Description: This function obtains information about a semaphore | |||
* | |||
* Arguments : pevent is a pointer to the event control block associated with the desired | |||
* semaphore | |||
* | |||
* p_sem_data is a pointer to a structure that will contain information about the | |||
* semaphore. | |||
* | |||
* Returns : OS_ERR_NONE The call was successful and the message was sent | |||
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* OS_ERR_PDATA_NULL If 'p_sem_data' is a NULL pointer | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_SEM_QUERY_EN > 0u | |||
INT8U OSSemQuery (OS_EVENT *pevent, | |||
OS_SEM_DATA *p_sem_data) | |||
{ | |||
INT8U i; | |||
OS_PRIO *psrc; | |||
OS_PRIO *pdest; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
return (OS_ERR_PEVENT_NULL); | |||
} | |||
if (p_sem_data == (OS_SEM_DATA *)0) { /* Validate 'p_sem_data' */ | |||
return (OS_ERR_PDATA_NULL); | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
return (OS_ERR_EVENT_TYPE); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
p_sem_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */ | |||
psrc = &pevent->OSEventTbl[0]; | |||
pdest = &p_sem_data->OSEventTbl[0]; | |||
for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) { | |||
*pdest++ = *psrc++; | |||
} | |||
p_sem_data->OSCnt = pevent->OSEventCnt; /* Get semaphore count */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif /* OS_SEM_QUERY_EN */ | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* SET SEMAPHORE | |||
* | |||
* Description: This function sets the semaphore count to the value specified as an argument. Typically, | |||
* this value would be 0. | |||
* | |||
* You would typically use this function when a semaphore is used as a signaling mechanism | |||
* and, you want to reset the count value. | |||
* | |||
* Arguments : pevent is a pointer to the event control block | |||
* | |||
* cnt is the new value for the semaphore count. You would pass 0 to reset the | |||
* semaphore count. | |||
* | |||
* perr is a pointer to an error code returned by the function as follows: | |||
* | |||
* OS_ERR_NONE The call was successful and the semaphore value was set. | |||
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore. | |||
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer. | |||
* OS_ERR_TASK_WAITING If tasks are waiting on the semaphore. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_SEM_SET_EN > 0u | |||
void OSSemSet (OS_EVENT *pevent, | |||
INT16U cnt, | |||
INT8U *perr) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
#ifdef OS_SAFETY_CRITICAL | |||
if (perr == (INT8U *)0) { | |||
OS_SAFETY_CRITICAL_EXCEPTION(); | |||
} | |||
#endif | |||
#if OS_ARG_CHK_EN > 0u | |||
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ | |||
*perr = OS_ERR_PEVENT_NULL; | |||
return; | |||
} | |||
#endif | |||
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ | |||
*perr = OS_ERR_EVENT_TYPE; | |||
return; | |||
} | |||
OS_ENTER_CRITICAL(); | |||
*perr = OS_ERR_NONE; | |||
if (pevent->OSEventCnt > 0u) { /* See if semaphore already has a count */ | |||
pevent->OSEventCnt = cnt; /* Yes, set it to the new value specified. */ | |||
} else { /* No */ | |||
if (pevent->OSEventGrp == 0u) { /* See if task(s) waiting? */ | |||
pevent->OSEventCnt = cnt; /* No, OK to set the value */ | |||
} else { | |||
*perr = OS_ERR_TASK_WAITING; | |||
} | |||
} | |||
OS_EXIT_CRITICAL(); | |||
} | |||
#endif | |||
#endif /* OS_SEM_EN */ | |||
@@ -0,0 +1,264 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* TIME MANAGEMENT | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : OS_TIME.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_MASTER_FILE | |||
#include <ucos_ii.h> | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* DELAY TASK 'n' TICKS | |||
* | |||
* Description: This function is called to delay execution of the currently running task until the | |||
* specified number of system ticks expires. This, of course, directly equates to delaying | |||
* the current task for some time to expire. No delay will result If the specified delay is | |||
* 0. If the specified delay is greater than 0 then, a context switch will result. | |||
* | |||
* Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'. | |||
* Note that by specifying 0, the task will not be delayed. | |||
* | |||
* Returns : none | |||
********************************************************************************************************* | |||
*/ | |||
void OSTimeDly (INT32U ticks) | |||
{ | |||
INT8U y; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ | |||
return; | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked */ | |||
return; | |||
} | |||
if (ticks > 0u) { /* 0 means no delay! */ | |||
OS_ENTER_CRITICAL(); | |||
y = OSTCBCur->OSTCBY; /* Delay current task */ | |||
OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; | |||
if (OSRdyTbl[y] == 0u) { | |||
OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; | |||
} | |||
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* Find next task to run! */ | |||
} | |||
} | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* DELAY TASK FOR SPECIFIED TIME | |||
* | |||
* Description: This function is called to delay execution of the currently running task until some time | |||
* expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and | |||
* MILLISECONDS instead of ticks. | |||
* | |||
* Arguments : hours specifies the number of hours that the task will be delayed (max. is 255) | |||
* minutes specifies the number of minutes (max. 59) | |||
* seconds specifies the number of seconds (max. 59) | |||
* ms specifies the number of milliseconds (max. 999) | |||
* | |||
* Returns : OS_ERR_NONE | |||
* OS_ERR_TIME_INVALID_MINUTES | |||
* OS_ERR_TIME_INVALID_SECONDS | |||
* OS_ERR_TIME_INVALID_MS | |||
* OS_ERR_TIME_ZERO_DLY | |||
* OS_ERR_TIME_DLY_ISR | |||
* | |||
* Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do | |||
* a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be | |||
* set to 0. The actual delay is rounded to the nearest tick. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_TIME_DLY_HMSM_EN > 0u | |||
INT8U OSTimeDlyHMSM (INT8U hours, | |||
INT8U minutes, | |||
INT8U seconds, | |||
INT16U ms) | |||
{ | |||
INT32U ticks; | |||
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ | |||
return (OS_ERR_TIME_DLY_ISR); | |||
} | |||
if (OSLockNesting > 0u) { /* See if called with scheduler locked */ | |||
return (OS_ERR_SCHED_LOCKED); | |||
} | |||
#if OS_ARG_CHK_EN > 0u | |||
if (hours == 0u) { | |||
if (minutes == 0u) { | |||
if (seconds == 0u) { | |||
if (ms == 0u) { | |||
return (OS_ERR_TIME_ZERO_DLY); | |||
} | |||
} | |||
} | |||
} | |||
if (minutes > 59u) { | |||
return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */ | |||
} | |||
if (seconds > 59u) { | |||
return (OS_ERR_TIME_INVALID_SECONDS); | |||
} | |||
if (ms > 999u) { | |||
return (OS_ERR_TIME_INVALID_MS); | |||
} | |||
#endif | |||
/* Compute the total number of clock ticks required.. */ | |||
/* .. (rounded to the nearest tick) */ | |||
ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC | |||
+ OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL; | |||
OSTimeDly(ticks); | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* RESUME A DELAYED TASK | |||
* | |||
* Description: This function is used resume a task that has been delayed through a call to either | |||
* OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a | |||
* task that is waiting for an event with timeout. This would make the task look | |||
* like a timeout occurred. | |||
* | |||
* Arguments : prio specifies the priority of the task to resume | |||
* | |||
* Returns : OS_ERR_NONE Task has been resumed | |||
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed | |||
* (i.e. >= OS_LOWEST_PRIO) | |||
* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire | |||
* OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_TIME_DLY_RESUME_EN > 0u | |||
INT8U OSTimeDlyResume (INT8U prio) | |||
{ | |||
OS_TCB *ptcb; | |||
#if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
if (prio >= OS_LOWEST_PRIO) { | |||
return (OS_ERR_PRIO_INVALID); | |||
} | |||
OS_ENTER_CRITICAL(); | |||
ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */ | |||
if (ptcb == (OS_TCB *)0) { | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ | |||
} | |||
if (ptcb == OS_TCB_RESERVED) { | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */ | |||
} | |||
if (ptcb->OSTCBDly == 0u) { /* See if task is delayed */ | |||
OS_EXIT_CRITICAL(); | |||
return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */ | |||
} | |||
ptcb->OSTCBDly = 0u; /* Clear the time delay */ | |||
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { | |||
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */ | |||
ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ | |||
} else { | |||
ptcb->OSTCBStatPend = OS_STAT_PEND_OK; | |||
} | |||
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ | |||
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ | |||
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; | |||
OS_EXIT_CRITICAL(); | |||
OS_Sched(); /* See if this is new highest priority */ | |||
} else { | |||
OS_EXIT_CRITICAL(); /* Task may be suspended */ | |||
} | |||
return (OS_ERR_NONE); | |||
} | |||
#endif | |||
/*$PAGE*/ | |||
/* | |||
********************************************************************************************************* | |||
* GET CURRENT SYSTEM TIME | |||
* | |||
* Description: This function is used by your application to obtain the current value of the 32-bit | |||
* counter which keeps track of the number of clock ticks. | |||
* | |||
* Arguments : none | |||
* | |||
* Returns : The current value of OSTime | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_TIME_GET_SET_EN > 0u | |||
INT32U OSTimeGet (void) | |||
{ | |||
INT32U ticks; | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
ticks = OSTime; | |||
OS_EXIT_CRITICAL(); | |||
return (ticks); | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* SET SYSTEM CLOCK | |||
* | |||
* Description: This function sets the 32-bit counter which keeps track of the number of clock ticks. | |||
* | |||
* Arguments : ticks specifies the new value that OSTime needs to take. | |||
* | |||
* Returns : none | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_TIME_GET_SET_EN > 0u | |||
void OSTimeSet (INT32U ticks) | |||
{ | |||
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ | |||
OS_CPU_SR cpu_sr = 0u; | |||
#endif | |||
OS_ENTER_CRITICAL(); | |||
OSTime = ticks; | |||
OS_EXIT_CRITICAL(); | |||
} | |||
#endif | |||
@@ -0,0 +1,38 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* | |||
* (c) Copyright 1992-2009, Micrium, Weston, FL | |||
* All Rights Reserved | |||
* | |||
* File : uCOS_II.C | |||
* By : Jean J. Labrosse | |||
* Version : V2.91 | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research. | |||
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license | |||
* its use in your product. We provide ALL the source code for your convenience and to help you experience | |||
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a | |||
* licensing fee. | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_GLOBALS /* Declare GLOBAL variables */ | |||
#include <ucos_ii.h> | |||
#define OS_MASTER_FILE /* Prevent the following files from including includes.h */ | |||
#include <os_core.c> | |||
#include <os_flag.c> | |||
#include <os_mbox.c> | |||
#include <os_mem.c> | |||
#include <os_mutex.c> | |||
#include <os_q.c> | |||
#include <os_sem.c> | |||
#include <os_task.c> | |||
#include <os_time.c> | |||
#include <os_tmr.c> | |||
@@ -0,0 +1,190 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* | |||
* | |||
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL | |||
* All rights reserved. Protected by international copyright laws. | |||
* | |||
* ARM Cortex-M4 Port | |||
* | |||
* File : OS_CPU.H | |||
* Version : V2.92.09 | |||
* By : JJL | |||
* JBL | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE short-term evaluation, for educational use or | |||
* for peaceful research. If you plan or intend to use uC/OS-II in a commercial application/ | |||
* product then, you need to contact Micrium to properly license uC/OS-II for its use in your | |||
* application/product. We provide ALL the source code for your convenience and to help you | |||
* experience uC/OS-II. The fact that the source is provided does NOT mean that you can use | |||
* it commercially without paying a licensing fee. | |||
* | |||
* Knowledge of the source code may NOT be used to develop a similar product. | |||
* | |||
* Please help us continue to provide the embedded community with the finest software available. | |||
* Your honesty is greatly appreciated. | |||
* | |||
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036. | |||
* | |||
* For : ARMv7 Cortex-M4 | |||
* Mode : Thumb-2 ISA | |||
* Toolchain : IAR EWARM | |||
********************************************************************************************************* | |||
*/ | |||
#ifndef OS_CPU_H | |||
#define OS_CPU_H | |||
#ifdef OS_CPU_GLOBALS | |||
#define OS_CPU_EXT | |||
#else | |||
#define OS_CPU_EXT extern | |||
#endif | |||
#ifndef OS_CPU_EXCEPT_STK_SIZE | |||
#define OS_CPU_EXCEPT_STK_SIZE 128u /* Default exception stack size is 128 OS_STK entries */ | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* DEFINES | |||
********************************************************************************************************* | |||
*/ | |||
#ifdef __ARMVFP__ | |||
#define OS_CPU_ARM_FP_EN 1u | |||
#else | |||
#define OS_CPU_ARM_FP_EN 0u | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* OS TICK INTERRUPT PRIORITY CONFIGURATION | |||
* | |||
* Note(s) : (1) For systems that don't need any high, real-time priority interrupts; the tick interrupt | |||
* should be configured as the highest priority interrupt but won't adversely affect system | |||
* operations. | |||
* | |||
* (2) For systems that need one or more high, real-time interrupts; these should be configured | |||
* higher than the tick interrupt which MAY delay execution of the tick interrupt. | |||
* | |||
* (a) If the higher priority interrupts do NOT continually consume CPU cycles but only | |||
* occasionally delay tick interrupts, then the real-time interrupts can successfully | |||
* handle their intermittent/periodic events with the system not losing tick interrupts | |||
* but only increasing the jitter. | |||
* | |||
* (b) If the higher priority interrupts consume enough CPU cycles to continually delay the | |||
* tick interrupt, then the CPU/system is most likely over-burdened & can't be expected | |||
* to handle all its interrupts/tasks. The system time reference gets compromised as a | |||
* result of losing tick interrupts. | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_CPU_CFG_SYSTICK_PRIO 0u | |||
/* | |||
********************************************************************************************************* | |||
* DATA TYPES | |||
* (Compiler Specific) | |||
********************************************************************************************************* | |||
*/ | |||
typedef unsigned char BOOLEAN; | |||
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ | |||
typedef signed char INT8S; /* Signed 8 bit quantity */ | |||
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */ | |||
typedef signed short INT16S; /* Signed 16 bit quantity */ | |||
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */ | |||
typedef signed int INT32S; /* Signed 32 bit quantity */ | |||
typedef float FP32; /* Single precision floating point */ | |||
typedef double FP64; /* Double precision floating point */ | |||
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */ | |||
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ | |||
/* | |||
********************************************************************************************************* | |||
* Cortex-M4 | |||
* Critical Section Management | |||
* | |||
* Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts | |||
* will be enabled even if they were disabled before entering the critical section. | |||
* NOT IMPLEMENTED | |||
* | |||
* Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if | |||
* interrupts were disabled before entering the critical section, they will be disabled when | |||
* leaving the critical section. | |||
* NOT IMPLEMENTED | |||
* | |||
* Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you | |||
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then | |||
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to | |||
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' | |||
* into the CPU's status register. | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_CRITICAL_METHOD 3u | |||
#if OS_CRITICAL_METHOD == 3u | |||
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();} | |||
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* Cortex-M4 Miscellaneous | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_STK_GROWTH 1u /* Stack grows from HIGH to LOW memory on ARM */ | |||
#define OS_TASK_SW() OSCtxSw() | |||
/* | |||
********************************************************************************************************* | |||
* GLOBAL VARIABLES | |||
********************************************************************************************************* | |||
*/ | |||
OS_CPU_EXT OS_STK OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE]; | |||
OS_CPU_EXT OS_STK *OS_CPU_ExceptStkBase; | |||
/* | |||
********************************************************************************************************* | |||
* FUNCTION PROTOTYPES | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CRITICAL_METHOD == 3u /* See OS_CPU_A.ASM */ | |||
OS_CPU_SR OS_CPU_SR_Save (void); | |||
void OS_CPU_SR_Restore (OS_CPU_SR cpu_sr); | |||
#endif | |||
void OSCtxSw (void); | |||
void OSIntCtxSw (void); | |||
void OSStartHighRdy (void); | |||
void OS_CPU_PendSVHandler (void); | |||
/* See OS_CPU_C.C */ | |||
//void OS_CPU_SysTickHandler (void); | |||
//void OS_CPU_SysTickInit (INT32U cnts); | |||
#if (OS_CPU_ARM_FP_EN > 0u) | |||
void OS_CPU_FP_Reg_Push (OS_STK *stkPtr); | |||
void OS_CPU_FP_Reg_Pop (OS_STK *stkPtr); | |||
#endif | |||
#endif |
@@ -0,0 +1,306 @@ | |||
; | |||
;******************************************************************************************************** | |||
; uC/OS-II | |||
; The Real-Time Kernel | |||
; | |||
; | |||
; (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL | |||
; All rights reserved. Protected by international copyright laws. | |||
; | |||
; ARM Cortex-M4 Port | |||
; | |||
; File : OS_CPU_A.ASM | |||
; Version : V2.92.09 | |||
; By : JJL | |||
; BAN | |||
; JBL | |||
; | |||
; For : ARMv7 Cortex-M4 | |||
; Mode : Thumb-2 ISA | |||
; Toolchain : IAR EWARM | |||
;******************************************************************************************************** | |||
; | |||
;******************************************************************************************************** | |||
; PUBLIC FUNCTIONS | |||
;******************************************************************************************************** | |||
EXTERN OSRunning ; External references | |||
EXTERN OSPrioCur | |||
EXTERN OSPrioHighRdy | |||
EXTERN OSTCBCur | |||
EXTERN OSTCBHighRdy | |||
EXTERN OSIntExit | |||
EXTERN OSTaskSwHook | |||
EXTERN OS_CPU_ExceptStkBase | |||
PUBLIC OS_CPU_SR_Save ; Functions declared in this file | |||
PUBLIC OS_CPU_SR_Restore | |||
PUBLIC OSStartHighRdy | |||
PUBLIC OSCtxSw | |||
PUBLIC OSIntCtxSw | |||
PUBLIC OS_CPU_PendSVHandler | |||
#ifdef __ARMVFP__ | |||
PUBLIC OS_CPU_FP_Reg_Push | |||
PUBLIC OS_CPU_FP_Reg_Pop | |||
#endif | |||
;******************************************************************************************************** | |||
; EQUATES | |||
;******************************************************************************************************** | |||
NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register. | |||
NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14). | |||
NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest). | |||
NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. | |||
;******************************************************************************************************** | |||
; CODE GENERATION DIRECTIVES | |||
;******************************************************************************************************** | |||
RSEG CODE:CODE:NOROOT(2) | |||
THUMB | |||
;******************************************************************************************************** | |||
; FLOATING POINT REGISTERS PUSH | |||
; void OS_CPU_FP_Reg_Push (OS_STK *stkPtr) | |||
; | |||
; Note(s) : 1) This function saves S0-S31, and FPSCR registers of the Floating Point Unit. | |||
; | |||
; 2) Pseudo-code is: | |||
; a) Get FPSCR register value; | |||
; b) Push value on process stack; | |||
; c) Push remaining regs S0-S31 on process stack; | |||
; d) Update OSTCBCur->OSTCBStkPtr; | |||
;******************************************************************************************************** | |||
#ifdef __ARMVFP__ | |||
OS_CPU_FP_Reg_Push | |||
MRS R1, PSP ; PSP is process stack pointer | |||
CBZ R1, OS_CPU_FP_nosave ; Skip FP register save the first time | |||
VMRS R1, FPSCR | |||
STR R1, [R0, #-4]! | |||
VSTMDB R0!, {S0-S31} | |||
LDR R1, =OSTCBCur | |||
LDR R2, [R1] | |||
STR R0, [R2] | |||
OS_CPU_FP_nosave | |||
BX LR | |||
#endif | |||
;******************************************************************************************************** | |||
; FLOATING POINT REGISTERS POP | |||
; void OS_CPU_FP_Reg_Pop (OS_STK *stkPtr) | |||
; | |||
; Note(s) : 1) This function restores S0-S31, and FPSCR registers of the Floating Point Unit. | |||
; | |||
; 2) Pseudo-code is: | |||
; a) Restore regs S0-S31 of new process stack; | |||
; b) Restore FPSCR reg value | |||
; c) Update OSTCBHighRdy->OSTCBStkPtr pointer of new proces stack; | |||
;******************************************************************************************************** | |||
#ifdef __ARMVFP__ | |||
OS_CPU_FP_Reg_Pop | |||
VLDMIA R0!, {S0-S31} | |||
LDMIA R0!, {R1} | |||
VMSR FPSCR, R1 | |||
LDR R1, =OSTCBHighRdy | |||
LDR R2, [R1] | |||
STR R0, [R2] | |||
BX LR | |||
#endif | |||
;******************************************************************************************************** | |||
; CRITICAL SECTION METHOD 3 FUNCTIONS | |||
; | |||
; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you | |||
; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then | |||
; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to | |||
; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr' | |||
; into the CPU's status register. | |||
; | |||
; Prototypes : OS_CPU_SR OS_CPU_SR_Save(void); | |||
; void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); | |||
; | |||
; | |||
; Note(s) : 1) These functions are used in general like this: | |||
; | |||
; void Task (void *p_arg) | |||
; { | |||
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ | |||
; OS_CPU_SR cpu_sr; | |||
; #endif | |||
; | |||
; : | |||
; : | |||
; OS_ENTER_CRITICAL(); /* cpu_sr = OS_CPU_SaveSR(); */ | |||
; : | |||
; : | |||
; OS_EXIT_CRITICAL(); /* OS_CPU_RestoreSR(cpu_sr); */ | |||
; : | |||
; : | |||
; } | |||
;******************************************************************************************************** | |||
OS_CPU_SR_Save | |||
MRS R0, PRIMASK ; Set prio int mask to mask all (except faults) | |||
CPSID I | |||
BX LR | |||
OS_CPU_SR_Restore | |||
MSR PRIMASK, R0 | |||
BX LR | |||
;******************************************************************************************************** | |||
; START MULTITASKING | |||
; void OSStartHighRdy(void) | |||
; | |||
; Note(s) : 1) This function triggers a PendSV exception (essentially, causes a context switch) to cause | |||
; the first task to start. | |||
; | |||
; 2) OSStartHighRdy() MUST: | |||
; a) Setup PendSV exception priority to lowest; | |||
; b) Set initial PSP to 0, to tell context switcher this is first run; | |||
; c) Set the main stack to OS_CPU_ExceptStkBase | |||
; d) Set OSRunning to TRUE; | |||
; e) Trigger PendSV exception; | |||
; f) Enable interrupts (tasks will run with interrupts enabled). | |||
;******************************************************************************************************** | |||
OSStartHighRdy | |||
LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority | |||
LDR R1, =NVIC_PENDSV_PRI | |||
STRB R1, [R0] | |||
MOVS R0, #0 ; Set the PSP to 0 for initial context switch call | |||
MSR PSP, R0 | |||
LDR R0, =OS_CPU_ExceptStkBase ; Initialize the MSP to the OS_CPU_ExceptStkBase | |||
LDR R1, [R0] | |||
MSR MSP, R1 | |||
LDR R0, =OSRunning ; OSRunning = TRUE | |||
MOVS R1, #1 | |||
STRB R1, [R0] | |||
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch) | |||
LDR R1, =NVIC_PENDSVSET | |||
STR R1, [R0] | |||
CPSIE I ; Enable interrupts at processor level | |||
OSStartHang | |||
B OSStartHang ; Should never get here | |||
;******************************************************************************************************** | |||
; PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw() | |||
; | |||
; Note(s) : 1) OSCtxSw() is called when OS wants to perform a task context switch. This function | |||
; triggers the PendSV exception which is where the real work is done. | |||
;******************************************************************************************************** | |||
OSCtxSw | |||
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch) | |||
LDR R1, =NVIC_PENDSVSET | |||
STR R1, [R0] | |||
BX LR | |||
;******************************************************************************************************** | |||
; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw() | |||
; | |||
; Note(s) : 1) OSIntCtxSw() is called by OSIntExit() when it determines a context switch is needed as | |||
; the result of an interrupt. This function simply triggers a PendSV exception which will | |||
; be handled when there are no more interrupts active and interrupts are enabled. | |||
;******************************************************************************************************** | |||
OSIntCtxSw | |||
LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch) | |||
LDR R1, =NVIC_PENDSVSET | |||
STR R1, [R0] | |||
BX LR | |||
;******************************************************************************************************** | |||
; HANDLE PendSV EXCEPTION | |||
; void OS_CPU_PendSVHandler(void) | |||
; | |||
; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing | |||
; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the | |||
; processor context on any exception, and restores same on return from exception. So only | |||
; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception | |||
; this way means that context saving and restoring is identical whether it is initiated from | |||
; a thread or occurs due to an interrupt or exception. | |||
; | |||
; 2) Pseudo-code is: | |||
; a) Get the process SP, if 0 then skip (goto d) the saving part (first context switch); | |||
; b) Save remaining regs r4-r11 on process stack; | |||
; c) Save the process SP in its TCB, OSTCBCur->OSTCBStkPtr = SP; | |||
; d) Call OSTaskSwHook(); | |||
; e) Get current high priority, OSPrioCur = OSPrioHighRdy; | |||
; f) Get current ready thread TCB, OSTCBCur = OSTCBHighRdy; | |||
; g) Get new process SP from TCB, SP = OSTCBHighRdy->OSTCBStkPtr; | |||
; h) Restore R4-R11 from new process stack; | |||
; i) Perform exception return which will restore remaining context. | |||
; | |||
; 3) On entry into PendSV handler: | |||
; a) The following have been saved on the process stack (by processor): | |||
; xPSR, PC, LR, R12, R0-R3 | |||
; b) Processor mode is switched to Handler mode (from Thread mode) | |||
; c) Stack is Main stack (switched from Process stack) | |||
; d) OSTCBCur points to the OS_TCB of the task to suspend | |||
; OSTCBHighRdy points to the OS_TCB of the task to resume | |||
; | |||
; 4) Since PendSV is set to lowest priority in the system (by OSStartHighRdy() above), we | |||
; know that it will only be run when no other exception or interrupt is active, and | |||
; therefore safe to assume that context being switched out was using the process stack (PSP). | |||
;******************************************************************************************************** | |||
OS_CPU_PendSVHandler | |||
CPSID I ; Prevent interruption during context switch | |||
MRS R0, PSP ; PSP is process stack pointer | |||
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time | |||
SUBS R0, R0, #0x20 ; Save remaining regs r4-11 on process stack | |||
STM R0, {R4-R11} | |||
LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP; | |||
LDR R1, [R1] | |||
STR R0, [R1] ; R0 is SP of process being switched out | |||
; At this point, entire context of process has been saved | |||
OS_CPU_PendSVHandler_nosave | |||
PUSH {R14} ; Save LR exc_return value | |||
LDR R0, =OSTaskSwHook ; OSTaskSwHook(); | |||
BLX R0 | |||
POP {R14} | |||
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; | |||
LDR R1, =OSPrioHighRdy | |||
LDRB R2, [R1] | |||
STRB R2, [R0] | |||
LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy; | |||
LDR R1, =OSTCBHighRdy | |||
LDR R2, [R1] | |||
STR R2, [R0] | |||
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr; | |||
LDM R0, {R4-R11} ; Restore r4-11 from new process stack | |||
ADDS R0, R0, #0x20 | |||
MSR PSP, R0 ; Load PSP with new process SP | |||
ORR LR, LR, #0xF4 ; Ensure exception return uses process stack | |||
CPSIE I | |||
BX LR ; Exception return will restore remaining context | |||
END |
@@ -0,0 +1,623 @@ | |||
/* | |||
********************************************************************************************************* | |||
* uC/OS-II | |||
* The Real-Time Kernel | |||
* | |||
* | |||
* (c) Copyright 2009-2013; Micrium, Inc.; Weston, FL | |||
* All rights reserved. Protected by international copyright laws. | |||
* | |||
* ARM Cortex-M4 Port | |||
* | |||
* File : OS_CPU_C.C | |||
* Version : V2.92.09 | |||
* By : JJL | |||
* BAN | |||
* | |||
* LICENSING TERMS: | |||
* --------------- | |||
* uC/OS-II is provided in source form for FREE short-term evaluation, for educational use or | |||
* for peaceful research. If you plan or intend to use uC/OS-II in a commercial application/ | |||
* product then, you need to contact Micrium to properly license uC/OS-II for its use in your | |||
* experience uC/OS-II. The fact that the source is provided does NOT mean that you can use | |||
* it commercially without paying a licensing fee. | |||
* | |||
* Knowledge of the source code may NOT be used to develop a similar product. | |||
* | |||
* Please help us continue to provide the embedded community with the finest software available. | |||
* Your honesty is greatly appreciated. | |||
* | |||
* You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036. | |||
* | |||
* For : ARMv7 Cortex-M4 | |||
* Mode : Thumb-2 ISA | |||
* Toolchain : IAR EWARM | |||
********************************************************************************************************* | |||
*/ | |||
#define OS_CPU_GLOBALS | |||
/* | |||
********************************************************************************************************* | |||
* INCLUDE FILES | |||
********************************************************************************************************* | |||
*/ | |||
#include <ucos_ii.h> | |||
//#include <lib_def.h> | |||
/********************************************************************************************************* | |||
* LOCAL VARIABLES | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_TMR_EN > 0u | |||
static INT16U OSTmrCtr; | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* SYS TICK DEFINES | |||
********************************************************************************************************* | |||
*/ | |||
//#define OS_CPU_CM4_NVIC_ST_CTRL (*((volatile INT32U *)0xE000E010uL)) /* SysTick Ctrl & Status Reg. */ | |||
//#define OS_CPU_CM4_NVIC_ST_RELOAD (*((volatile INT32U *)0xE000E014uL)) /* SysTick Reload Value Reg. */ | |||
//#define OS_CPU_CM4_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018uL)) /* SysTick Current Value Reg. */ | |||
//#define OS_CPU_CM4_NVIC_ST_CAL (*((volatile INT32U *)0xE000E01CuL)) /* SysTick Cal Value Reg. */ | |||
//#define OS_CPU_CM4_NVIC_SHPRI1 (*((volatile INT32U *)0xE000ED18uL)) /* System Handlers 4 to 7 Prio. */ | |||
//#define OS_CPU_CM4_NVIC_SHPRI2 (*((volatile INT32U *)0xE000ED1CuL)) /* System Handlers 8 to 11 Prio. */ | |||
//#define OS_CPU_CM4_NVIC_SHPRI3 (*((volatile INT32U *)0xE000ED20uL)) /* System Handlers 12 to 15 Prio. */ | |||
#define OS_CPU_CM4_NVIC_ST_CTRL_COUNT 0x00010000uL /* Count flag. */ | |||
#define OS_CPU_CM4_NVIC_ST_CTRL_CLK_SRC 0x00000004uL /* Clock Source. */ | |||
#define OS_CPU_CM4_NVIC_ST_CTRL_INTEN 0x00000002uL /* Interrupt enable. */ | |||
#define OS_CPU_CM4_NVIC_ST_CTRL_ENABLE 0x00000001uL /* Counter mode. */ | |||
#define OS_CPU_CM4_NVIC_PRIO_MIN 0xFFu /* Min handler prio. */ | |||
/* | |||
********************************************************************************************************* | |||
* OS INITIALIZATION HOOK | |||
* (BEGINNING) | |||
* | |||
* Description: This function is called by OSInit() at the beginning of OSInit(). | |||
* | |||
* Arguments : none | |||
* | |||
* Note(s) : 1) Interrupts should be disabled during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSInitHookBegin (void) | |||
{ | |||
INT32U size; | |||
OS_STK *pstk; | |||
/* Clear exception stack for stack checking. */ | |||
pstk = &OS_CPU_ExceptStk[0]; | |||
size = OS_CPU_EXCEPT_STK_SIZE; | |||
while (size > 0u) { | |||
size--; | |||
*pstk++ = (OS_STK)0; | |||
} | |||
/* Align the ISR stack to 8-bytes */ | |||
OS_CPU_ExceptStkBase = (OS_STK *)&OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE]; | |||
OS_CPU_ExceptStkBase = (OS_STK *)((OS_STK)(OS_CPU_ExceptStkBase) & 0xFFFFFFF8); | |||
#if OS_TMR_EN > 0u | |||
OSTmrCtr = 0u; | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* OS INITIALIZATION HOOK | |||
* (END) | |||
* | |||
* Description: This function is called by OSInit() at the end of OSInit(). | |||
* | |||
* Arguments : none | |||
* | |||
* Note(s) : 1) Interrupts should be disabled during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSInitHookEnd (void) | |||
{ | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* TASK CREATION HOOK | |||
* | |||
* Description: This function is called when a task is created. | |||
* | |||
* Arguments : ptcb is a pointer to the task control block of the task being created. | |||
* | |||
* Note(s) : 1) Interrupts are disabled during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTaskCreateHook (OS_TCB *ptcb) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskCreateHook(ptcb); | |||
#else | |||
(void)ptcb; /* Prevent compiler warning */ | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* TASK DELETION HOOK | |||
* | |||
* Description: This function is called when a task is deleted. | |||
* | |||
* Arguments : ptcb is a pointer to the task control block of the task being deleted. | |||
* | |||
* Note(s) : 1) Interrupts are disabled during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTaskDelHook (OS_TCB *ptcb) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskDelHook(ptcb); | |||
#else | |||
(void)ptcb; /* Prevent compiler warning */ | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* IDLE TASK HOOK | |||
* | |||
* Description: This function is called by the idle task. This hook has been added to allow you to do | |||
* such things as STOP the CPU to conserve power. | |||
* | |||
* Arguments : none | |||
* | |||
* Note(s) : 1) Interrupts are enabled during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTaskIdleHook (void) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskIdleHook(); | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* TASK RETURN HOOK | |||
* | |||
* Description: This function is called if a task accidentally returns. In other words, a task should | |||
* either be an infinite loop or delete itself when done. | |||
* | |||
* Arguments : ptcb is a pointer to the task control block of the task that is returning. | |||
* | |||
* Note(s) : none | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTaskReturnHook (OS_TCB *ptcb) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskReturnHook(ptcb); | |||
#else | |||
(void)ptcb; | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* STATISTIC TASK HOOK | |||
* | |||
* Description: This function is called every second by uC/OS-II's statistics task. This allows your | |||
* application to add functionality to the statistics task. | |||
* | |||
* Arguments : none | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTaskStatHook (void) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskStatHook(); | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* INITIALIZE A TASK'S STACK | |||
* | |||
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the | |||
* stack frame of the task being created. This function is highly processor specific. | |||
* | |||
* Arguments : task is a pointer to the task code | |||
* | |||
* p_arg is a pointer to a user supplied data area that will be passed to the task | |||
* when the task first executes. | |||
* | |||
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to | |||
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then | |||
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if | |||
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address | |||
* of the stack. | |||
* | |||
* opt specifies options that can be used to alter the behavior of OSTaskStkInit(). | |||
* (see uCOS_II.H for OS_TASK_OPT_xxx). | |||
* | |||
* Returns : Always returns the location of the new top-of-stack once the processor registers have | |||
* been placed on the stack in the proper order. | |||
* | |||
* Note(s) : (1) Interrupts are enabled when task starts executing. | |||
* | |||
* (2) All tasks run in Thread mode, using process stack. | |||
* | |||
* (3) There are two different stack frames depending on whether the Floating-Point(FP) | |||
* co-processor is enabled or not. | |||
* | |||
* (a) The stack frame shown in the diagram is used when the FP co-processor is not present and | |||
* OS_TASK_OPT_SAVE_FP is disabled. In this case, the FP registers and FP Status Control | |||
* register are not saved in the stack frame. | |||
* | |||
* (b) If the FP co-processor is present but the OS_TASK_OPT_SAVE_FP is not set, then the stack | |||
* frame is saved as shown in diagram (a). Moreover, if OS_TASK_OPT_SAVE_FP is set, then the | |||
* FP registers and FP Status Control register are saved in the stack frame. | |||
* | |||
* (1) When enabling the FP co-processor, make sure to clear bits ASPEN and LSPEN in the | |||
* Floating-Point Context Control Register (FPCCR). | |||
* | |||
* +------------+ +------------+ | |||
* | | | | | |||
* +------------+ +------------+ | |||
* | xPSR | | xPSR | | |||
* +------------+ +------------+ | |||
* |Return Addr | |Return Addr | | |||
* +------------+ +------------+ | |||
* | LR(R14) | | LR(R14) | | |||
* +------------+ +------------+ | |||
* | R12 | | R12 | | |||
* +------------+ +------------+ | |||
* | R3 | | R3 | | |||
* +------------+ +------------+ | |||
* | R2 | | R0 | | |||
* +------------+ +------------+ | |||
* | R1 | | R1 | | |||
* +------------+ +------------+ | |||
* | R0 | | R0 | | |||
* +------------+ +------------+ | |||
* | R11 | | R11 | | |||
* +------------+ +------------+ | |||
* | R10 | | R10 | | |||
* +------------+ +------------+ | |||
* | R9 | | R9 | | |||
* +------------+ +------------+ | |||
* | R8 | | R8 | | |||
* +------------+ +------------+ | |||
* | R7 | | R7 | | |||
* +------------+ +------------+ | |||
* | R6 | | R6 | | |||
* +------------+ +------------+ | |||
* | R5 | | R5 | | |||
* +------------+ +------------+ | |||
* | R4 | | R4 | | |||
* +------------+ +------------+ | |||
* (a) | FPSCR | | |||
* +------------+ | |||
* | S31 | | |||
* +------------+ | |||
* . | |||
* . | |||
* . | |||
* +------------+ | |||
* | S1 | | |||
+------------+ | |||
* | S0 | | |||
* +------------+ | |||
* (b) | |||
* | |||
* (4) The SP must be 8-byte aligned in conforming to the Procedure Call Standard for the ARM architecture | |||
* | |||
* (a) Section 2.1 of the ABI for the ARM Architecture Advisory Note. SP must be 8-byte aligned | |||
* on entry to AAPCS-Conforming functions states : | |||
* | |||
* The Procedure Call Standard for the ARM Architecture [AAPCS] requires primitive | |||
* data types to be naturally aligned according to their sizes (for size = 1, 2, 4, 8 bytes). | |||
* Doing otherwise creates more problems than it solves. | |||
* | |||
* In return for preserving the natural alignment of data, conforming code is permitted | |||
* to rely on that alignment. To support aligning data allocated on the stack, the stack | |||
* pointer (SP) is required to be 8-byte aligned on entry to a conforming function. In | |||
* practice this requirement is met if: | |||
* | |||
* (1) At each call site, the current size of the calling function’s stack frame is a multiple of 8 bytes. | |||
* This places an obligation on compilers and assembly language programmers. | |||
* | |||
* (2) SP is a multiple of 8 when control first enters a program. | |||
* This places an obligation on authors of low level OS, RTOS, and runtime library | |||
* code to align SP at all points at which control first enters | |||
* a body of (AAPCS-conforming) code. | |||
* | |||
* In turn, this requires the value of SP to be aligned to 0 modulo 8: | |||
* | |||
* (3) By exception handlers, before calling AAPCS-conforming code. | |||
* | |||
* (4) By OS/RTOS/run-time system code, before giving control to an application. | |||
* | |||
* (b) Section 2.3.1 corrective steps from the the SP must be 8-byte aligned on entry | |||
* to AAPCS-conforming functions advisory note also states. | |||
* | |||
* " This requirement extends to operating systems and run-time code for all architecture versions | |||
* prior to ARMV7 and to the A, R and M architecture profiles thereafter. Special considerations | |||
* associated with ARMV7M are discussed in §2.3.3" | |||
* | |||
* (1) Even if the SP 8-byte aligment is not a requirement for the ARMv7M profile, the stack is aligned | |||
* to 8-byte boundaries to support legacy execution enviroments. | |||
* | |||
* (c) Section 5.2.1.2 from the Procedure Call Standard for the ARM | |||
* architecture states : "The stack must also conform to the following | |||
* constraint at a public interface: | |||
* | |||
* (1) SP mod 8 = 0. The stack must be double-word aligned" | |||
* | |||
* (d) From the ARM Technical Support Knowledge Base. 8 Byte stack aligment. | |||
* | |||
* "8 byte stack alignment is a requirement of the ARM Architecture Procedure | |||
* Call Standard [AAPCS]. This specifies that functions must maintain an 8 byte | |||
* aligned stack address (e.g. 0x00, 0x08, 0x10, 0x18, 0x20) on all external | |||
* interfaces. In practice this requirement is met if: | |||
* | |||
* (1) At each external interface, the current stack pointer | |||
* is a multiple of 8 bytes. | |||
* | |||
* (2) Your OS maintains 8 byte stack alignment on its external interfaces | |||
* e.g. on task switches" | |||
* | |||
********************************************************************************************************** | |||
*/ | |||
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt) | |||
{ | |||
OS_STK *p_stk; | |||
p_stk = ptos + 1u; /* Load stack pointer */ | |||
/* Align the stack to 8-bytes. */ | |||
p_stk = (OS_STK *)((OS_STK)(p_stk) & 0xFFFFFFF8u); | |||
/* Registers stacked as if auto-saved on exception */ | |||
*(--p_stk) = (OS_STK)0x01000000uL; /* xPSR */ | |||
*(--p_stk) = (OS_STK)task; /* Entry Point */ | |||
*(--p_stk) = (OS_STK)OS_TaskReturn; /* R14 (LR) */ | |||
*(--p_stk) = (OS_STK)0x12121212uL; /* R12 */ | |||
*(--p_stk) = (OS_STK)0x03030303uL; /* R3 */ | |||
*(--p_stk) = (OS_STK)0x02020202uL; /* R2 */ | |||
*(--p_stk) = (OS_STK)0x01010101uL; /* R1 */ | |||
*(--p_stk) = (OS_STK)p_arg; /* R0 : argument */ | |||
/* Remaining registers saved on process stack */ | |||
*(--p_stk) = (OS_STK)0x11111111uL; /* R11 */ | |||
*(--p_stk) = (OS_STK)0x10101010uL; /* R10 */ | |||
*(--p_stk) = (OS_STK)0x09090909uL; /* R9 */ | |||
*(--p_stk) = (OS_STK)0x08080808uL; /* R8 */ | |||
*(--p_stk) = (OS_STK)0x07070707uL; /* R7 */ | |||
*(--p_stk) = (OS_STK)0x06060606uL; /* R6 */ | |||
*(--p_stk) = (OS_STK)0x05050505uL; /* R5 */ | |||
*(--p_stk) = (OS_STK)0x04040404uL; /* R4 */ | |||
#if (OS_CPU_ARM_FP_EN > 0u) | |||
if ((opt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) { | |||
*--p_stk = (OS_STK)0x02000000u; /* FPSCR */ | |||
/* Initialize S0-S31 floating point registers */ | |||
*--p_stk = (OS_STK)0x41F80000u; /* S31 */ | |||
*--p_stk = (OS_STK)0x41F00000u; /* S30 */ | |||
*--p_stk = (OS_STK)0x41E80000u; /* S29 */ | |||
*--p_stk = (OS_STK)0x41E00000u; /* S28 */ | |||
*--p_stk = (OS_STK)0x41D80000u; /* S27 */ | |||
*--p_stk = (OS_STK)0x41D00000u; /* S26 */ | |||
*--p_stk = (OS_STK)0x41C80000u; /* S25 */ | |||
*--p_stk = (OS_STK)0x41C00000u; /* S24 */ | |||
*--p_stk = (OS_STK)0x41B80000u; /* S23 */ | |||
*--p_stk = (OS_STK)0x41B00000u; /* S22 */ | |||
*--p_stk = (OS_STK)0x41A80000u; /* S21 */ | |||
*--p_stk = (OS_STK)0x41A00000u; /* S20 */ | |||
*--p_stk = (OS_STK)0x41980000u; /* S19 */ | |||
*--p_stk = (OS_STK)0x41900000u; /* S18 */ | |||
*--p_stk = (OS_STK)0x41880000u; /* S17 */ | |||
*--p_stk = (OS_STK)0x41800000u; /* S16 */ | |||
*--p_stk = (OS_STK)0x41700000u; /* S15 */ | |||
*--p_stk = (OS_STK)0x41600000u; /* S14 */ | |||
*--p_stk = (OS_STK)0x41500000u; /* S13 */ | |||
*--p_stk = (OS_STK)0x41400000u; /* S12 */ | |||
*--p_stk = (OS_STK)0x41300000u; /* S11 */ | |||
*--p_stk = (OS_STK)0x41200000u; /* S10 */ | |||
*--p_stk = (OS_STK)0x41100000u; /* S9 */ | |||
*--p_stk = (OS_STK)0x41000000u; /* S8 */ | |||
*--p_stk = (OS_STK)0x40E00000u; /* S7 */ | |||
*--p_stk = (OS_STK)0x40C00000u; /* S6 */ | |||
*--p_stk = (OS_STK)0x40A00000u; /* S5 */ | |||
*--p_stk = (OS_STK)0x40800000u; /* S4 */ | |||
*--p_stk = (OS_STK)0x40400000u; /* S3 */ | |||
*--p_stk = (OS_STK)0x40000000u; /* S2 */ | |||
*--p_stk = (OS_STK)0x3F800000u; /* S1 */ | |||
*--p_stk = (OS_STK)0x00000000u; /* S0 */ | |||
} | |||
#endif | |||
return (p_stk); | |||
} | |||
/* | |||
********************************************************************************************************* | |||
* TASK SWITCH HOOK | |||
* | |||
* Description: This function is called when a task switch is performed. This allows you to perform other | |||
* operations during a context switch. | |||
* | |||
* Arguments : none | |||
* | |||
* Note(s) : 1) Interrupts are disabled during this call. | |||
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that | |||
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the | |||
* task being switched out (i.e. the preempted task). | |||
********************************************************************************************************* | |||
*/ | |||
#if (OS_CPU_HOOKS_EN > 0u) && (OS_TASK_SW_HOOK_EN > 0u) | |||
void OSTaskSwHook (void) | |||
{ | |||
#if (OS_CPU_ARM_FP_EN > 0u) | |||
if ((OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) { | |||
OS_CPU_FP_Reg_Push(OSTCBCur->OSTCBStkPtr); | |||
} | |||
if ((OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) != (INT16U)0) { | |||
OS_CPU_FP_Reg_Pop(OSTCBHighRdy->OSTCBStkPtr); | |||
} | |||
#endif | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TaskSwHook(); | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* OS_TCBInit() HOOK | |||
* | |||
* Description: This function is called by OS_TCBInit() after setting up most of the TCB. | |||
* | |||
* Arguments : ptcb is a pointer to the TCB of the task being created. | |||
* | |||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if OS_CPU_HOOKS_EN > 0u | |||
void OSTCBInitHook (OS_TCB *ptcb) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TCBInitHook(ptcb); | |||
#else | |||
(void)ptcb; /* Prevent compiler warning */ | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* TICK HOOK | |||
* | |||
* Description: This function is called every tick. | |||
* | |||
* Arguments : none | |||
* | |||
* Note(s) : 1) Interrupts may or may not be ENABLED during this call. | |||
********************************************************************************************************* | |||
*/ | |||
#if (OS_CPU_HOOKS_EN > 0u) && (OS_TIME_TICK_HOOK_EN > 0u) | |||
void OSTimeTickHook (void) | |||
{ | |||
#if OS_APP_HOOKS_EN > 0u | |||
App_TimeTickHook(); | |||
#endif | |||
#if OS_TMR_EN > 0u | |||
OSTmrCtr++; | |||
if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) { | |||
OSTmrCtr = 0; | |||
OSTmrSignal(); | |||
} | |||
#endif | |||
} | |||
#endif | |||
/* | |||
********************************************************************************************************* | |||
* SYS TICK HANDLER | |||
* | |||
* Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick | |||
* interrupt. | |||
* | |||
* Arguments : None. | |||
* | |||
* Note(s) : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table. | |||
********************************************************************************************************* | |||
*/ | |||
/* | |||
void OS_CPU_SysTickHandler (void) | |||
{ | |||
OS_CPU_SR cpu_sr; | |||
OS_ENTER_CRITICAL(); | |||
OSIntNesting++; | |||
OS_EXIT_CRITICAL(); | |||
OSTimeTick(); | |||
OSIntExit(); | |||
} | |||
*/ | |||
/* | |||
********************************************************************************************************* | |||
* INITIALIZE SYS TICK | |||
* | |||
* Description: Initialize the SysTick. | |||
* | |||
* Arguments : cnts Number of SysTick counts between two OS tick interrupts. | |||
* | |||
* Note(s) : 1) This function MUST be called after OSStart() & after processor initialization. | |||
********************************************************************************************************* | |||
*/ | |||
/*void OS_CPU_SysTickInit (INT32U cnts) | |||
{ | |||
INT32U prio; | |||
OS_CPU_CM4_NVIC_ST_RELOAD = cnts - 1u; | |||
prio = OS_CPU_CM4_NVIC_SHPRI3; | |||
prio &= DEF_BIT_FIELD(24, 0); | |||
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24); | |||
OS_CPU_CM4_NVIC_SHPRI3 = prio; | |||
OS_CPU_CM4_NVIC_ST_CTRL |= OS_CPU_CM4_NVIC_ST_CTRL_CLK_SRC | | |||
OS_CPU_CM4_NVIC_ST_CTRL_ENABLE; | |||
OS_CPU_CM4_NVIC_ST_CTRL |= OS_CPU_CM4_NVIC_ST_CTRL_INTEN; | |||
} | |||
*/ |