From a01c70df53928fae360d1828c0c83b5f1acd4b84 Mon Sep 17 00:00:00 2001 From: QQyyblithe Date: Thu, 21 Jul 2022 16:30:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4UCOS=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP/EXTI/exti.c | 63 + APP/EXTI/exti.h | 42 + APP/LED/led.c | 74 + APP/LED/led.h | 40 + APP/TIMER/timer.c | 31 + APP/TIMER/timer.h | 10 + APP/delay/delay.c | 305 + APP/delay/delay.h | 55 + APP/main.c | 388 ++ APP/main.h | 6 + APP/stm32f4xx.h | 9175 +++++++++++++++++++++++++ APP/stm32f4xx_conf.h | 125 + APP/stm32f4xx_it.c | 170 + APP/stm32f4xx_it.h | 60 + APP/sys/sys.c | 49 + APP/sys/sys.h | 83 + APP/system_stm32f4xx.c | 1142 +++ APP/system_stm32f4xx.h | 105 + CMSIS/core_cm4.h | 1772 +++++ CMSIS/core_cm4_simd.h | 673 ++ CMSIS/core_cmFunc.h | 636 ++ CMSIS/core_cmInstr.h | 688 ++ DRIVER/inc/misc.h | 178 + DRIVER/inc/stm32f4xx_exti.h | 183 + DRIVER/inc/stm32f4xx_gpio.h | 502 ++ DRIVER/inc/stm32f4xx_rcc.h | 630 ++ DRIVER/inc/stm32f4xx_syscfg.h | 210 + DRIVER/inc/stm32f4xx_tim.h | 1150 ++++ DRIVER/src/misc.c | 249 + DRIVER/src/stm32f4xx_exti.c | 311 + DRIVER/src/stm32f4xx_gpio.c | 611 ++ DRIVER/src/stm32f4xx_rcc.c | 2307 +++++++ DRIVER/src/stm32f4xx_syscfg.c | 240 + DRIVER/src/stm32f4xx_tim.c | 3365 +++++++++ IAR/settings/task01.Debug.cspy.bat | 40 + IAR/settings/task01.Debug.cspy.ps1 | 31 + IAR/settings/task01.Debug.driver.xcl | 29 + IAR/settings/task01.Debug.general.xcl | 15 + IAR/settings/task01.crun | 13 + IAR/settings/task01.dbgdt | 1044 +++ IAR/settings/task01.dnx | 155 + IAR/settings/task01.wsdt | 413 ++ IAR/startup_stm32f40_41xxx.s | 636 ++ IAR/task01.dep | 812 +++ IAR/task01.ewd | 2966 ++++++++ IAR/task01.ewp | 2228 ++++++ IAR/task01.eww | 7 + UCOS/CONFIG/includes.h | 56 + UCOS/CONFIG/os_cfg.h | 144 + UCOS/CORE/os_core.c | 2028 ++++++ UCOS/CORE/os_flag.c | 1215 ++++ UCOS/CORE/os_mbox.c | 647 ++ UCOS/CORE/os_mem.c | 456 ++ UCOS/CORE/os_mutex.c | 735 ++ UCOS/CORE/os_q.c | 893 +++ UCOS/CORE/os_sem.c | 629 ++ UCOS/CORE/os_task.c | 1263 ++++ UCOS/CORE/os_time.c | 264 + UCOS/CORE/os_tmr.c | 1073 +++ UCOS/CORE/ucos_ii.c | 38 + UCOS/CORE/ucos_ii.h | 1896 +++++ UCOS/PORT/os_cpu.h | 190 + UCOS/PORT/os_cpu_a.asm | 306 + UCOS/PORT/os_cpu_c.c | 623 ++ 64 files changed, 46473 insertions(+) create mode 100644 APP/EXTI/exti.c create mode 100644 APP/EXTI/exti.h create mode 100644 APP/LED/led.c create mode 100644 APP/LED/led.h create mode 100644 APP/TIMER/timer.c create mode 100644 APP/TIMER/timer.h create mode 100644 APP/delay/delay.c create mode 100644 APP/delay/delay.h create mode 100644 APP/main.c create mode 100644 APP/main.h create mode 100644 APP/stm32f4xx.h create mode 100644 APP/stm32f4xx_conf.h create mode 100644 APP/stm32f4xx_it.c create mode 100644 APP/stm32f4xx_it.h create mode 100644 APP/sys/sys.c create mode 100644 APP/sys/sys.h create mode 100644 APP/system_stm32f4xx.c create mode 100644 APP/system_stm32f4xx.h create mode 100644 CMSIS/core_cm4.h create mode 100644 CMSIS/core_cm4_simd.h create mode 100644 CMSIS/core_cmFunc.h create mode 100644 CMSIS/core_cmInstr.h create mode 100644 DRIVER/inc/misc.h create mode 100644 DRIVER/inc/stm32f4xx_exti.h create mode 100644 DRIVER/inc/stm32f4xx_gpio.h create mode 100644 DRIVER/inc/stm32f4xx_rcc.h create mode 100644 DRIVER/inc/stm32f4xx_syscfg.h create mode 100644 DRIVER/inc/stm32f4xx_tim.h create mode 100644 DRIVER/src/misc.c create mode 100644 DRIVER/src/stm32f4xx_exti.c create mode 100644 DRIVER/src/stm32f4xx_gpio.c create mode 100644 DRIVER/src/stm32f4xx_rcc.c create mode 100644 DRIVER/src/stm32f4xx_syscfg.c create mode 100644 DRIVER/src/stm32f4xx_tim.c create mode 100644 IAR/settings/task01.Debug.cspy.bat create mode 100644 IAR/settings/task01.Debug.cspy.ps1 create mode 100644 IAR/settings/task01.Debug.driver.xcl create mode 100644 IAR/settings/task01.Debug.general.xcl create mode 100644 IAR/settings/task01.crun create mode 100644 IAR/settings/task01.dbgdt create mode 100644 IAR/settings/task01.dnx create mode 100644 IAR/settings/task01.wsdt create mode 100644 IAR/startup_stm32f40_41xxx.s create mode 100644 IAR/task01.dep create mode 100644 IAR/task01.ewd create mode 100644 IAR/task01.ewp create mode 100644 IAR/task01.eww create mode 100644 UCOS/CONFIG/includes.h create mode 100644 UCOS/CONFIG/os_cfg.h create mode 100644 UCOS/CORE/os_core.c create mode 100644 UCOS/CORE/os_flag.c create mode 100644 UCOS/CORE/os_mbox.c create mode 100644 UCOS/CORE/os_mem.c create mode 100644 UCOS/CORE/os_mutex.c create mode 100644 UCOS/CORE/os_q.c create mode 100644 UCOS/CORE/os_sem.c create mode 100644 UCOS/CORE/os_task.c create mode 100644 UCOS/CORE/os_time.c create mode 100644 UCOS/CORE/os_tmr.c create mode 100644 UCOS/CORE/ucos_ii.c create mode 100644 UCOS/CORE/ucos_ii.h create mode 100644 UCOS/PORT/os_cpu.h create mode 100644 UCOS/PORT/os_cpu_a.asm create mode 100644 UCOS/PORT/os_cpu_c.c diff --git a/APP/EXTI/exti.c b/APP/EXTI/exti.c new file mode 100644 index 0000000..d970e5b --- /dev/null +++ b/APP/EXTI/exti.c @@ -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);//ÅäÖà + +} + + + + + + + + + + + + diff --git a/APP/EXTI/exti.h b/APP/EXTI/exti.h new file mode 100644 index 0000000..f8947c3 --- /dev/null +++ b/APP/EXTI/exti.h @@ -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 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/APP/LED/led.c b/APP/LED/led.c new file mode 100644 index 0000000..63393cb --- /dev/null +++ b/APP/LED/led.c @@ -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); +} + + + + + + diff --git a/APP/LED/led.h b/APP/LED/led.h new file mode 100644 index 0000000..a1000d5 --- /dev/null +++ b/APP/LED/led.h @@ -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 diff --git a/APP/TIMER/timer.c b/APP/TIMER/timer.c new file mode 100644 index 0000000..0fcb756 --- /dev/null +++ b/APP/TIMER/timer.c @@ -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); +} + diff --git a/APP/TIMER/timer.h b/APP/TIMER/timer.h new file mode 100644 index 0000000..8f490db --- /dev/null +++ b/APP/TIMER/timer.h @@ -0,0 +1,10 @@ +#ifndef _TIMER_H +#define _TIMER_H + +/***********************Í·Îļþ****************************/ +#include "sys.h" + +/***********************º¯ÊýÉùÃ÷****************************/ +void TIM3_Int_Init(u16 arr,u16 psc); + +#endif diff --git a/APP/delay/delay.c b/APP/delay/delay.c new file mode 100644 index 0000000..019dfa0 --- /dev/null +++ b/APP/delay/delay.c @@ -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=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) + { + + } + } + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/APP/delay/delay.h b/APP/delay/delay.h new file mode 100644 index 0000000..09c4359 --- /dev/null +++ b/APP/delay/delay.h @@ -0,0 +1,55 @@ +#ifndef __DELAY_H +#define __DELAY_H +#include +////////////////////////////////////////////////////////////////////////////////// +//±¾³ÌÐòÖ»¹©Ñ§Ï°Ê¹Óã¬Î´¾­×÷ÕßÐí¿É£¬²»µÃÓÃÓÚÆäËüÈκÎÓÃ; +//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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/APP/main.c b/APP/main.c new file mode 100644 index 0000000..19d5138 --- /dev/null +++ b/APP/main.c @@ -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(); //Í˳öÖжϴ¦Àí +} + + + + + + + + diff --git a/APP/main.h b/APP/main.h new file mode 100644 index 0000000..4713ef9 --- /dev/null +++ b/APP/main.h @@ -0,0 +1,6 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#include "includes.h" +OS_EVENT * msg_TaskC; //ÈÎÎñCÏûÏ¢ÓÊÏä +#endif \ No newline at end of file diff --git a/APP/stm32f4xx.h b/APP/stm32f4xx.h new file mode 100644 index 0000000..96f650d --- /dev/null +++ b/APP/stm32f4xx.h @@ -0,0 +1,9175 @@ +/** + ****************************************************************************** + * @file stm32f4xx.h + * @author MCD Application Team + * @version V1.4.0 + * @date 04-August-2014 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F4xx devices. + * + * The file is the unique include file that the application programmer + * is using in the C source code, usually in main.c. This file contains: + * - Configuration section that allows to select: + * - The device used in the target application + * - To use or not the peripheral’s drivers in application code(i.e. + * code will be based on direct access to peripheral’s registers + * rather than drivers API), this option is controlled by + * "#define USE_STDPERIPH_DRIVER" + * - To change few application-specific parameters such as the HSE + * crystal frequency + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripheral’s registers hardware + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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 + * @{ + */ + +#ifndef __STM32F4xx_H +#define __STM32F4xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F40_41xxx) && !defined (STM32F427_437xx) && !defined (STM32F429_439xx) && !defined (STM32F401xx) && !defined (STM32F411xE) + /* #define STM32F40_41xxx */ /*!< STM32F405RG, STM32F405VG, STM32F405ZG, STM32F415RG, STM32F415VG, STM32F415ZG, + STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG, STM32F407IE, + STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */ + + /* #define STM32F427_437xx */ /*!< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG, STM32F427II, + STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG, STM32F437II Devices */ + + /* #define STM32F429_439xx */ /*!< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI, + STM32F429NG, STM32F439NI, STM32F429IG, STM32F429II, STM32F439VG, STM32F439VI, + STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG, STM32F439NI, + STM32F439IG and STM32F439II Devices */ + + /* #define STM32F401xx */ /*!< STM32F401CB, STM32F401CC, STM32F401RB, STM32F401RC, STM32F401VB, STM32F401VC + STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CExx, STM32F401RE and STM32F401VE Devices */ + + /* #define STM32F411xE */ /*!< STM32F411CD, STM32F411RD, STM32F411VD, STM32F411CE, STM32F411RE and STM32F411VE Devices */ +#endif + +/* Old STM32F40XX definition, maintained for legacy purpose */ +#ifdef STM32F40XX + #define STM32F40_41xxx +#endif /* STM32F40XX */ + +/* Old STM32F427X definition, maintained for legacy purpose */ +#ifdef STM32F427X + #define STM32F427_437xx +#endif /* STM32F427X */ + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (STM32F40_41xxx) && !defined (STM32F427_437xx) && !defined (STM32F429_439xx) && !defined (STM32F401xx) && !defined (STM32F411xE) + #error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)" +#endif + +#if !defined (USE_STDPERIPH_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_STDPERIPH_DRIVER */ +#endif /* USE_STDPERIPH_DRIVER */ + +/** + * @brief In the following line adjust the value of External High Speed oscillator (HSE) + used in your application + + Tip: To avoid modifying this file each time you need to use different HSE, you + can define the HSE value in your toolchain compiler preprocessor. + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ + +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint16_t)0x05000) /*!< Time out for HSE start up */ +#endif /* HSE_STARTUP_TIMEOUT */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief STM32F4XX Standard Peripherals Library version number V1.4.0 + */ +#define __STM32F4XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB1 (0x04) /*!< [23:16] sub1 version */ +#define __STM32F4XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32F4XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F4XX_STDPERIPH_VERSION ((__STM32F4XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__STM32F4XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__STM32F4XX_STDPERIPH_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present */ + +/** + * @brief STM32F4XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + +#if defined (STM32F40_41xxx) + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81 /*!< FPU global interrupt */ +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FMC_IRQn = 48, /*!< FMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81, /*!< FPU global interrupt */ + UART7_IRQn = 82, /*!< UART7 global interrupt */ + UART8_IRQn = 83, /*!< UART8 global interrupt */ + SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ + SPI5_IRQn = 85, /*!< SPI5 global Interrupt */ + SPI6_IRQn = 86, /*!< SPI6 global Interrupt */ + SAI1_IRQn = 87, /*!< SAI1 global Interrupt */ + DMA2D_IRQn = 90 /*!< DMA2D global Interrupt */ +#endif /* STM32F427_437xx */ + +#if defined (STM32F429_439xx) + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FMC_IRQn = 48, /*!< FMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81, /*!< FPU global interrupt */ + UART7_IRQn = 82, /*!< UART7 global interrupt */ + UART8_IRQn = 83, /*!< UART8 global interrupt */ + SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ + SPI5_IRQn = 85, /*!< SPI5 global Interrupt */ + SPI6_IRQn = 86, /*!< SPI6 global Interrupt */ + SAI1_IRQn = 87, /*!< SAI1 global Interrupt */ + LTDC_IRQn = 88, /*!< LTDC global Interrupt */ + LTDC_ER_IRQn = 89, /*!< LTDC Error global Interrupt */ + DMA2D_IRQn = 90 /*!< DMA2D global Interrupt */ +#endif /* STM32F429_439xx */ + +#if defined (STM32F401xx) || defined (STM32F411xE) + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + FPU_IRQn = 81, /*!< FPU global interrupt */ +#if defined (STM32F401xx) + SPI4_IRQn = 84 /*!< SPI4 global Interrupt */ +#endif /* STM32F411xE */ +#if defined (STM32F411xE) + SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ + SPI5_IRQn = 85 /*!< SPI5 global Interrupt */ +#endif /* STM32F411xE */ +#endif /* STM32F401xx || STM32F411xE */ + +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "system_stm32f4xx.h" +#include + +/** @addtogroup Exported_types + * @{ + */ +/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< Read Only */ +typedef const int16_t sc16; /*!< Read Only */ +typedef const int8_t sc8; /*!< Read Only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< Read Only */ +typedef __I int16_t vsc16; /*!< Read Only */ +typedef __I int8_t vsc8; /*!< Read Only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< Read Only */ +typedef const uint16_t uc16; /*!< Read Only */ +typedef const uint8_t uc8; /*!< Read Only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< Read Only */ +typedef __I uint16_t vuc16; /*!< Read Only */ +typedef __I uint8_t vuc8; /*!< Read Only */ + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** + * @} + */ + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DCMI + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + +/** + * @brief DMA2D Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA2D Control Register, Address offset: 0x00 */ + __IO uint32_t ISR; /*!< DMA2D Interrupt Status Register, Address offset: 0x04 */ + __IO uint32_t IFCR; /*!< DMA2D Interrupt Flag Clear Register, Address offset: 0x08 */ + __IO uint32_t FGMAR; /*!< DMA2D Foreground Memory Address Register, Address offset: 0x0C */ + __IO uint32_t FGOR; /*!< DMA2D Foreground Offset Register, Address offset: 0x10 */ + __IO uint32_t BGMAR; /*!< DMA2D Background Memory Address Register, Address offset: 0x14 */ + __IO uint32_t BGOR; /*!< DMA2D Background Offset Register, Address offset: 0x18 */ + __IO uint32_t FGPFCCR; /*!< DMA2D Foreground PFC Control Register, Address offset: 0x1C */ + __IO uint32_t FGCOLR; /*!< DMA2D Foreground Color Register, Address offset: 0x20 */ + __IO uint32_t BGPFCCR; /*!< DMA2D Background PFC Control Register, Address offset: 0x24 */ + __IO uint32_t BGCOLR; /*!< DMA2D Background Color Register, Address offset: 0x28 */ + __IO uint32_t FGCMAR; /*!< DMA2D Foreground CLUT Memory Address Register, Address offset: 0x2C */ + __IO uint32_t BGCMAR; /*!< DMA2D Background CLUT Memory Address Register, Address offset: 0x30 */ + __IO uint32_t OPFCCR; /*!< DMA2D Output PFC Control Register, Address offset: 0x34 */ + __IO uint32_t OCOLR; /*!< DMA2D Output Color Register, Address offset: 0x38 */ + __IO uint32_t OMAR; /*!< DMA2D Output Memory Address Register, Address offset: 0x3C */ + __IO uint32_t OOR; /*!< DMA2D Output Offset Register, Address offset: 0x40 */ + __IO uint32_t NLR; /*!< DMA2D Number of Line Register, Address offset: 0x44 */ + __IO uint32_t LWR; /*!< DMA2D Line Watermark Register, Address offset: 0x48 */ + __IO uint32_t AMTCR; /*!< DMA2D AHB Master Timer Configuration Register, Address offset: 0x4C */ + uint32_t RESERVED[236]; /*!< Reserved, 0x50-0x3FF */ + __IO uint32_t FGCLUT[256]; /*!< DMA2D Foreground CLUT, Address offset:400-7FF */ + __IO uint32_t BGCLUT[256]; /*!< DMA2D Background CLUT, Address offset:800-BFF */ +} DMA2D_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1[2]; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register , Address offset: 0x14 */ + __IO uint32_t OPTCR1; /*!< FLASH option control register 1, Address offset: 0x18 */ +} FLASH_TypeDef; + +#if defined (STM32F40_41xxx) +/** + * @brief Flexible Static Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FSMC_Bank1E_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ +} FSMC_Bank2_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FSMC_Bank3_TypeDef; + +/** + * @brief Flexible Static Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FSMC_Bank4_TypeDef; +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +/** + * @brief Flexible Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FMC_Bank1_TypeDef; + +/** + * @brief Flexible Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FMC_Bank1E_TypeDef; + +/** + * @brief Flexible Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ +} FMC_Bank2_TypeDef; + +/** + * @brief Flexible Memory Controller Bank3 + */ + +typedef struct +{ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FMC_Bank3_TypeDef; + +/** + * @brief Flexible Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FMC_Bank4_TypeDef; + +/** + * @brief Flexible Memory Controller Bank5_6 + */ + +typedef struct +{ + __IO uint32_t SDCR[2]; /*!< SDRAM Control registers , Address offset: 0x140-0x144 */ + __IO uint32_t SDTR[2]; /*!< SDRAM Timing registers , Address offset: 0x148-0x14C */ + __IO uint32_t SDCMR; /*!< SDRAM Command Mode register, Address offset: 0x150 */ + __IO uint32_t SDRTR; /*!< SDRAM Refresh Timer register, Address offset: 0x154 */ + __IO uint32_t SDSR; /*!< SDRAM Status register, Address offset: 0x158 */ +} FMC_Bank5_6_TypeDef; +#endif /* STM32F427_437xx || STM32F429_439xx */ + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint16_t FLTR; /*!< I2C FLTR register, Address offset: 0x24 */ + uint16_t RESERVED9; /*!< Reserved, 0x26 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + +/** + * @brief LCD-TFT Display Controller + */ + +typedef struct +{ + uint32_t RESERVED0[2]; /*!< Reserved, 0x00-0x04 */ + __IO uint32_t SSCR; /*!< LTDC Synchronization Size Configuration Register, Address offset: 0x08 */ + __IO uint32_t BPCR; /*!< LTDC Back Porch Configuration Register, Address offset: 0x0C */ + __IO uint32_t AWCR; /*!< LTDC Active Width Configuration Register, Address offset: 0x10 */ + __IO uint32_t TWCR; /*!< LTDC Total Width Configuration Register, Address offset: 0x14 */ + __IO uint32_t GCR; /*!< LTDC Global Control Register, Address offset: 0x18 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x1C-0x20 */ + __IO uint32_t SRCR; /*!< LTDC Shadow Reload Configuration Register, Address offset: 0x24 */ + uint32_t RESERVED2[1]; /*!< Reserved, 0x28 */ + __IO uint32_t BCCR; /*!< LTDC Background Color Configuration Register, Address offset: 0x2C */ + uint32_t RESERVED3[1]; /*!< Reserved, 0x30 */ + __IO uint32_t IER; /*!< LTDC Interrupt Enable Register, Address offset: 0x34 */ + __IO uint32_t ISR; /*!< LTDC Interrupt Status Register, Address offset: 0x38 */ + __IO uint32_t ICR; /*!< LTDC Interrupt Clear Register, Address offset: 0x3C */ + __IO uint32_t LIPCR; /*!< LTDC Line Interrupt Position Configuration Register, Address offset: 0x40 */ + __IO uint32_t CPSR; /*!< LTDC Current Position Status Register, Address offset: 0x44 */ + __IO uint32_t CDSR; /*!< LTDC Current Display Status Register, Address offset: 0x48 */ +} LTDC_TypeDef; + +/** + * @brief LCD-TFT Display layer x Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< LTDC Layerx Control Register Address offset: 0x84 */ + __IO uint32_t WHPCR; /*!< LTDC Layerx Window Horizontal Position Configuration Register Address offset: 0x88 */ + __IO uint32_t WVPCR; /*!< LTDC Layerx Window Vertical Position Configuration Register Address offset: 0x8C */ + __IO uint32_t CKCR; /*!< LTDC Layerx Color Keying Configuration Register Address offset: 0x90 */ + __IO uint32_t PFCR; /*!< LTDC Layerx Pixel Format Configuration Register Address offset: 0x94 */ + __IO uint32_t CACR; /*!< LTDC Layerx Constant Alpha Configuration Register Address offset: 0x98 */ + __IO uint32_t DCCR; /*!< LTDC Layerx Default Color Configuration Register Address offset: 0x9C */ + __IO uint32_t BFCR; /*!< LTDC Layerx Blending Factors Configuration Register Address offset: 0xA0 */ + uint32_t RESERVED0[2]; /*!< Reserved */ + __IO uint32_t CFBAR; /*!< LTDC Layerx Color Frame Buffer Address Register Address offset: 0xAC */ + __IO uint32_t CFBLR; /*!< LTDC Layerx Color Frame Buffer Length Register Address offset: 0xB0 */ + __IO uint32_t CFBLNR; /*!< LTDC Layerx ColorFrame Buffer Line Number Register Address offset: 0xB4 */ + uint32_t RESERVED1[3]; /*!< Reserved */ + __IO uint32_t CLUTWR; /*!< LTDC Layerx CLUT Write Register Address offset: 0x144 */ + +} LTDC_Layer_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ + __IO uint32_t PLLSAICFGR; /*!< RCC PLLSAI configuration register, Address offset: 0x88 */ + __IO uint32_t DCKCFGR; /*!< RCC Dedicated Clocks configuration register, Address offset: 0x8C */ + +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + + +/** + * @brief Serial Audio Interface + */ + +typedef struct +{ + __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ +} SAI_TypeDef; + +typedef struct +{ + __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ + __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ + __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ + __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ + __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ + __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ +} SAI_Block_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ + __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + uint16_t RESERVED7; /*!< Reserved, 0x1E */ + __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + uint16_t RESERVED8; /*!< Reserved, 0x22 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + uint16_t RESERVED9; /*!< Reserved, 0x2A */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + uint16_t RESERVED10; /*!< Reserved, 0x32 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + uint16_t RESERVED11; /*!< Reserved, 0x46 */ + __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + uint16_t RESERVED12; /*!< Reserved, 0x4A */ + __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + uint16_t RESERVED13; /*!< Reserved, 0x4E */ + __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */ + uint16_t RESERVED14; /*!< Reserved, 0x52 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */ + uint16_t RESERVED0; /*!< Reserved, 0x02 */ + __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + uint16_t RESERVED2; /*!< Reserved, 0x0A */ + __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + uint16_t RESERVED3; /*!< Reserved, 0x0E */ + __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + uint16_t RESERVED4; /*!< Reserved, 0x12 */ + __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + uint16_t RESERVED5; /*!< Reserved, 0x16 */ + __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ + uint16_t RESERVED6; /*!< Reserved, 0x1A */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief Crypto Processor + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ + __IO uint32_t CSGCMCCM0R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 0, Address offset: 0x50 */ + __IO uint32_t CSGCMCCM1R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 1, Address offset: 0x54 */ + __IO uint32_t CSGCMCCM2R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 2, Address offset: 0x58 */ + __IO uint32_t CSGCMCCM3R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 3, Address offset: 0x5C */ + __IO uint32_t CSGCMCCM4R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 4, Address offset: 0x60 */ + __IO uint32_t CSGCMCCM5R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 5, Address offset: 0x64 */ + __IO uint32_t CSGCMCCM6R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 6, Address offset: 0x68 */ + __IO uint32_t CSGCMCCM7R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 7, Address offset: 0x6C */ + __IO uint32_t CSGCM0R; /*!< CRYP GCM/GMAC context swap register 0, Address offset: 0x70 */ + __IO uint32_t CSGCM1R; /*!< CRYP GCM/GMAC context swap register 1, Address offset: 0x74 */ + __IO uint32_t CSGCM2R; /*!< CRYP GCM/GMAC context swap register 2, Address offset: 0x78 */ + __IO uint32_t CSGCM3R; /*!< CRYP GCM/GMAC context swap register 3, Address offset: 0x7C */ + __IO uint32_t CSGCM4R; /*!< CRYP GCM/GMAC context swap register 4, Address offset: 0x80 */ + __IO uint32_t CSGCM5R; /*!< CRYP GCM/GMAC context swap register 5, Address offset: 0x84 */ + __IO uint32_t CSGCM6R; /*!< CRYP GCM/GMAC context swap register 6, Address offset: 0x88 */ + __IO uint32_t CSGCM7R; /*!< CRYP GCM/GMAC context swap register 7, Address offset: 0x8C */ +} CRYP_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[54]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1CC */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ + +typedef struct +{ + __IO uint32_t HR[8]; /*!< HASH digest registers, Address offset: 0x310-0x32C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ +} RNG_TypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH(up to 1 MB) base address in the alias region */ +#define CCMDATARAM_BASE ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ +#define SRAM1_BASE ((uint32_t)0x20000000) /*!< SRAM1(112 KB) base address in the alias region */ +#define SRAM2_BASE ((uint32_t)0x2001C000) /*!< SRAM2(16 KB) base address in the alias region */ +#define SRAM3_BASE ((uint32_t)0x20020000) /*!< SRAM3(64 KB) base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ +#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */ + +#if defined (STM32F40_41xxx) +#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */ +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +#define FMC_R_BASE ((uint32_t)0xA0000000) /*!< FMC registers base address */ +#endif /* STM32F427_437xx || STM32F429_439xx */ + +#define CCMDATARAM_BB_BASE ((uint32_t)0x12000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the bit-band region */ +#define SRAM1_BB_BASE ((uint32_t)0x22000000) /*!< SRAM1(112 KB) base address in the bit-band region */ +#define SRAM2_BB_BASE ((uint32_t)0x2201C000) /*!< SRAM2(16 KB) base address in the bit-band region */ +#define SRAM3_BB_BASE ((uint32_t)0x22400000) /*!< SRAM3(64 KB) base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ +#define BKPSRAM_BB_BASE ((uint32_t)0x42024000) /*!< Backup SRAM(4 KB) base address in the bit-band region */ + +/* Legacy defines */ +#define SRAM_BASE SRAM1_BASE +#define SRAM_BB_BASE SRAM1_BB_BASE + + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400) +#define UART7_BASE (APB1PERIPH_BASE + 0x7800) +#define UART8_BASE (APB1PERIPH_BASE + 0x7C00) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) +#define TIM8_BASE (APB2PERIPH_BASE + 0x0400) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2100) +#define ADC3_BASE (APB2PERIPH_BASE + 0x2200) +#define ADC_BASE (APB2PERIPH_BASE + 0x2300) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define SPI4_BASE (APB2PERIPH_BASE + 0x3400) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) +#define SPI5_BASE (APB2PERIPH_BASE + 0x5000) +#define SPI6_BASE (APB2PERIPH_BASE + 0x5400) +#define SAI1_BASE (APB2PERIPH_BASE + 0x5800) +#define SAI1_Block_A_BASE (SAI1_BASE + 0x004) +#define SAI1_Block_B_BASE (SAI1_BASE + 0x024) +#define LTDC_BASE (APB2PERIPH_BASE + 0x6800) +#define LTDC_Layer1_BASE (LTDC_BASE + 0x84) +#define LTDC_Layer2_BASE (LTDC_BASE + 0x104) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400) +#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) +#define GPIOJ_BASE (AHB1PERIPH_BASE + 0x2400) +#define GPIOK_BASE (AHB1PERIPH_BASE + 0x2800) +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100) +#define ETH_PTP_BASE (ETH_BASE + 0x0700) +#define ETH_DMA_BASE (ETH_BASE + 0x1000) +#define DMA2D_BASE (AHB1PERIPH_BASE + 0xB000) + +/*!< AHB2 peripherals */ +#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000) +#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000) +#define HASH_BASE (AHB2PERIPH_BASE + 0x60400) +#define HASH_DIGEST_BASE (AHB2PERIPH_BASE + 0x60710) +#define RNG_BASE (AHB2PERIPH_BASE + 0x60800) + +#if defined (STM32F40_41xxx) +/*!< FSMC Bankx registers base address */ +#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) +#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) +#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) +#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) +#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +/*!< FMC Bankx registers base address */ +#define FMC_Bank1_R_BASE (FMC_R_BASE + 0x0000) +#define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104) +#define FMC_Bank2_R_BASE (FMC_R_BASE + 0x0060) +#define FMC_Bank3_R_BASE (FMC_R_BASE + 0x0080) +#define FMC_Bank4_R_BASE (FMC_R_BASE + 0x00A0) +#define FMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140) +#endif /* STM32F427_437xx || STM32F429_439xx */ + +/* Debug MCU registers base address */ +#define DBGMCU_BASE ((uint32_t )0xE0042000) + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) +#define UART7 ((USART_TypeDef *) UART7_BASE) +#define UART8 ((USART_TypeDef *) UART8_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI4 ((SPI_TypeDef *) SPI4_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define SPI5 ((SPI_TypeDef *) SPI5_BASE) +#define SPI6 ((SPI_TypeDef *) SPI6_BASE) +#define SAI1 ((SAI_TypeDef *) SAI1_BASE) +#define SAI1_Block_A ((SAI_Block_TypeDef *)SAI1_Block_A_BASE) +#define SAI1_Block_B ((SAI_Block_TypeDef *)SAI1_Block_B_BASE) +#define LTDC ((LTDC_TypeDef *)LTDC_BASE) +#define LTDC_Layer1 ((LTDC_Layer_TypeDef *)LTDC_Layer1_BASE) +#define LTDC_Layer2 ((LTDC_Layer_TypeDef *)LTDC_Layer2_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) +#define GPIOJ ((GPIO_TypeDef *) GPIOJ_BASE) +#define GPIOK ((GPIO_TypeDef *) GPIOK_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define DMA2D ((DMA2D_TypeDef *)DMA2D_BASE) +#define DCMI ((DCMI_TypeDef *) DCMI_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define HASH_DIGEST ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) + +#if defined (STM32F40_41xxx) +#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) +#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) +#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE) +#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE) +#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE) +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +#define FMC_Bank1 ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE) +#define FMC_Bank1E ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE) +#define FMC_Bank2 ((FMC_Bank2_TypeDef *) FMC_Bank2_R_BASE) +#define FMC_Bank3 ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE) +#define FMC_Bank4 ((FMC_Bank4_TypeDef *) FMC_Bank4_R_BASE) +#define FMC_Bank5_6 ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE) +#endif /* STM32F427_437xx || STM32F429_439xx */ + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint8_t)0x01) /*!
© COPYRIGHT 2014 STMicroelectronics
+ * + * 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****/ diff --git a/APP/stm32f4xx_it.c b/APP/stm32f4xx_it.c new file mode 100644 index 0000000..fd0cb9e --- /dev/null +++ b/APP/stm32f4xx_it.c @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/APP/stm32f4xx_it.h b/APP/stm32f4xx_it.h new file mode 100644 index 0000000..57cdbe7 --- /dev/null +++ b/APP/stm32f4xx_it.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/APP/sys/sys.c b/APP/sys/sys.c new file mode 100644 index 0000000..448a9cb --- /dev/null +++ b/APP/sys/sys.c @@ -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"); +} +//¹Ø±ÕËùÓÐÖжÏ(µ«ÊDz»°üÀ¨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 +//} +// + + + + + + + + + + + + + + + diff --git a/APP/sys/sys.h b/APP/sys/sys.h new file mode 100644 index 0000000..948aadd --- /dev/null +++ b/APP/sys/sys.h @@ -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¿ØÖƹ¦ÄÜ +//¾ßÌåʵÏÖ˼Ïë,²Î¿¼<>µÚÎåÕÂ(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 + + + + + + + + + + + diff --git a/APP/system_stm32f4xx.c b/APP/system_stm32f4xx.c new file mode 100644 index 0000000..5d3c8f6 --- /dev/null +++ b/APP/system_stm32f4xx.c @@ -0,0 +1,1142 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @version V1.4.0 + * @date 04-August-2014 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * This file contains the system clock configuration for STM32F4xx devices. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier + * and Divider factors, AHB/APBx prescalers and Flash settings), + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. If the system clock source selected by user fails to startup, the SystemInit() + * function will do nothing and HSI still used as system clock source. User can + * add some code to deal with this issue inside the SetSysClock() function. + * + * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define + * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or + * through PLL, and you are using different crystal you have to adapt the HSE + * value to your own configuration. + * + * 5. This file configures the system clock as follows: + *============================================================================= + *============================================================================= + * Supported STM32F40xxx/41xxx devices + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSE) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 168000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 4 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 2 + *----------------------------------------------------------------------------- + * HSE Frequency(Hz) | 25000000 + *----------------------------------------------------------------------------- + * PLL_M | 25 + *----------------------------------------------------------------------------- + * PLL_N | 336 + *----------------------------------------------------------------------------- + * PLL_P | 2 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * Main regulator output voltage | Scale1 mode + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 5 + *----------------------------------------------------------------------------- + * Prefetch Buffer | ON + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + *============================================================================= + * Supported STM32F42xxx/43xxx devices + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSE) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 180000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 180000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 4 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 2 + *----------------------------------------------------------------------------- + * HSE Frequency(Hz) | 25000000 + *----------------------------------------------------------------------------- + * PLL_M | 25 + *----------------------------------------------------------------------------- + * PLL_N | 360 + *----------------------------------------------------------------------------- + * PLL_P | 2 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * Main regulator output voltage | Scale1 mode + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 5 + *----------------------------------------------------------------------------- + * Prefetch Buffer | ON + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + *============================================================================= + * Supported STM32F401xx devices + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSE) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 84000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 84000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 2 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSE Frequency(Hz) | 25000000 + *----------------------------------------------------------------------------- + * PLL_M | 25 + *----------------------------------------------------------------------------- + * PLL_N | 336 + *----------------------------------------------------------------------------- + * PLL_P | 4 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * Main regulator output voltage | Scale1 mode + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 2 + *----------------------------------------------------------------------------- + * Prefetch Buffer | ON + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + *============================================================================= + * Supported STM32F411xx devices + *----------------------------------------------------------------------------- + * System Clock source | PLL (HSI) + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 100000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 100000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 2 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSI Frequency(Hz) | 16000000 + *----------------------------------------------------------------------------- + * PLL_M | 16 + *----------------------------------------------------------------------------- + * PLL_N | 400 + *----------------------------------------------------------------------------- + * PLL_P | 4 + *----------------------------------------------------------------------------- + * PLL_Q | 7 + *----------------------------------------------------------------------------- + * PLLI2S_N | NA + *----------------------------------------------------------------------------- + * PLLI2S_R | NA + *----------------------------------------------------------------------------- + * I2S input clock | NA + *----------------------------------------------------------------------------- + * VDD(V) | 3.3 + *----------------------------------------------------------------------------- + * Main regulator output voltage | Scale1 mode + *----------------------------------------------------------------------------- + * Flash Latency(WS) | 3 + *----------------------------------------------------------------------------- + * Prefetch Buffer | ON + *----------------------------------------------------------------------------- + * Instruction cache | ON + *----------------------------------------------------------------------------- + * Data cache | ON + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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 + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + +#include "stm32f4xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted + on STM324xG_EVAL/STM324x7I_EVAL/STM324x9I_EVAL boards as data memory */ +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F411xE) +/*!< Uncomment the following line if you need to clock the STM32F411xE by HSE Bypass + through STLINK MCO pin of STM32F103 microcontroller. The frequency cannot be changed + and is fixed at 8 MHz. + Hardware configuration needed for Nucleo Board: + – SB54, SB55 OFF + – R35 removed + – SB16, SB50 ON */ +/* #define USE_HSE_BYPASS */ + +#if defined (USE_HSE_BYPASS) +#define HSE_BYPASS_INPUT_FREQUENCY 8000000 +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F411xE */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/************************* PLL Parameters *************************************/ +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) +/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ +#define PLL_M 16 +#else /* STM32F411xE */ +#if defined (USE_HSE_BYPASS) +#define PLL_M 8 +#else /* STM32F411xE */ +#define PLL_M 16 +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ + +/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ +#define PLL_Q 7 + +#if defined (STM32F40_41xxx) +#define PLL_N 336 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +#define PLL_N 360 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 +#endif /* STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F401xx) +#define PLL_N 336 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 4 +#endif /* STM32F401xx */ + +#if defined (STM32F411xE) +#define PLL_N 400 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 4 +#endif /* STM32F411xx */ + +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + +#if defined (STM32F40_41xxx) + uint32_t SystemCoreClock = 168000000; +#endif /* STM32F40_41xxx */ + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) + uint32_t SystemCoreClock = 180000000; +#endif /* STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F401xx) + uint32_t SystemCoreClock = 84000000; +#endif /* STM32F401xx */ + +#if defined (STM32F411xE) + uint32_t SystemCoreClock = 100000000; +#endif /* STM32F401xx */ + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SetSysClock(void); + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemFrequency variable. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings ----------------------------------*/ + SetSysClock(); + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#elif defined (STM32F411xE) +#if defined (USE_HSE_BYPASS) + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_BYPASS_INPUT_FREQUENCY / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#else + if (pllsource == 0) + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief Configures the System clock source, PLL Multiplier and Divider factors, + * AHB/APBx prescalers and Flash settings + * @Note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). + * @param None + * @retval None + */ +static void SetSysClock(void) +{ +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + //__IO uint32_t StartUpCounter = 0, HSIStatus = 0; + + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + + /* Enable HSI */ + //RCC->CR |= ((uint32_t)RCC_CR_HSION); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + /* Wait till HSI is ready and if Time out is reached exit */ +// do +// { +// HSIStatus = RCC->CR & RCC_CR_HSIRDY; +// StartUpCounter++; +// } while((HSIStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_VOS; + + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; +#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F401xx) + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; +#endif /* STM32F401xx */ + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ + PWR->CR |= PWR_CR_ODEN; + while((PWR->CSR & PWR_CSR_ODRDY) == 0) + { + } + PWR->CR |= PWR_CR_ODSWEN; + while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) + { + } + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; +#endif /* STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F40_41xxx) + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; +#endif /* STM32F40_41xxx */ + +#if defined (STM32F401xx) + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; +#endif /* STM32F401xx */ + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +#elif defined (STM32F411xE) +#if defined (USE_HSE_BYPASS) +/******************************************************************************/ +/* PLL (clocked by HSE) used as System clock source */ +/******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + /* Enable HSE and HSE BYPASS */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode */ + 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_DIV1; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +#else /* HSI will be used as PLL clock source */ + /* Select regulator voltage output Scale 1 mode */ + 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_DIV1; + + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; + + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24); + + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; + + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ +} + +/** + * @brief Setup the external memory controller. Called in startup_stm32f4xx.s + * before jump to __main + * @param None + * @retval None + */ +#ifdef DATA_IN_ExtSRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external SRAM mounted on STM324xG_EVAL/STM324x7I boards + * This SRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+------------------+--------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+--------------+ + | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | + | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | + | PD4 <-> FMC_NOE | PE3 <-> FMC_A19 | PF2 <-> FMC_A2 | PG2 <-> FMC_A12 | + | PD5 <-> FMC_NWE | PE4 <-> FMC_A20 | PF3 <-> FMC_A3 | PG3 <-> FMC_A13 | + | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF4 <-> FMC_A4 | PG4 <-> FMC_A14 | + | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF5 <-> FMC_A5 | PG5 <-> FMC_A15 | + | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF12 <-> FMC_A6 | PG9 <-> FMC_NE2 | + | PD11 <-> FMC_A16 | PE10 <-> FMC_D7 | PF13 <-> FMC_A7 |-----------------+ + | PD12 <-> FMC_A17 | PE11 <-> FMC_D8 | PF14 <-> FMC_A8 | + | PD13 <-> FMC_A18 | PE12 <-> FMC_D9 | PF15 <-> FMC_A9 | + | PD14 <-> FMC_D0 | PE13 <-> FMC_D10 |-----------------+ + | PD15 <-> FMC_D1 | PE14 <-> FMC_D11 | + | | PE15 <-> FMC_D12 | + +------------------+------------------+ +*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00cc00cc; + GPIOD->AFR[1] = 0xcccccccc; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xaaaa0a0a; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xffff0f0f; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xcccccccc; + GPIOE->AFR[1] = 0xcccccccc; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xaaaaaaaa; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xffffffff; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xcccc0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xaa000aaa; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xff000fff; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00cccccc; + GPIOG->AFR[1] = 0x000000c0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00080aaa; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000c0fff; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC Configuration ------------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427_437xx || STM32F429_439xx */ + +#if defined (STM32F40_41xxx) + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F40_41xxx */ + +/* + Bank1_SRAM2 is configured as follow: + In case of FSMC configuration + NORSRAMTimingStructure.FSMC_AddressSetupTime = 1; + NORSRAMTimingStructure.FSMC_AddressHoldTime = 0; + NORSRAMTimingStructure.FSMC_DataSetupTime = 2; + NORSRAMTimingStructure.FSMC_BusTurnAroundDuration = 0; + NORSRAMTimingStructure.FSMC_CLKDivision = 0; + NORSRAMTimingStructure.FSMC_DataLatency = 0; + NORSRAMTimingStructure.FSMC_AccessMode = FMC_AccessMode_A; + + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &NORSRAMTimingStructure; + + In case of FMC configuration + NORSRAMTimingStructure.FMC_AddressSetupTime = 1; + NORSRAMTimingStructure.FMC_AddressHoldTime = 0; + NORSRAMTimingStructure.FMC_DataSetupTime = 2; + NORSRAMTimingStructure.FMC_BusTurnAroundDuration = 0; + NORSRAMTimingStructure.FMC_CLKDivision = 0; + NORSRAMTimingStructure.FMC_DataLatency = 0; + NORSRAMTimingStructure.FMC_AccessMode = FMC_AccessMode_A; + + FMC_NORSRAMInitStructure.FMC_Bank = FMC_Bank1_NORSRAM2; + FMC_NORSRAMInitStructure.FMC_DataAddressMux = FMC_DataAddressMux_Disable; + FMC_NORSRAMInitStructure.FMC_MemoryType = FMC_MemoryType_SRAM; + FMC_NORSRAMInitStructure.FMC_MemoryDataWidth = FMC_MemoryDataWidth_16b; + FMC_NORSRAMInitStructure.FMC_BurstAccessMode = FMC_BurstAccessMode_Disable; + FMC_NORSRAMInitStructure.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable; + FMC_NORSRAMInitStructure.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low; + FMC_NORSRAMInitStructure.FMC_WrapMode = FMC_WrapMode_Disable; + FMC_NORSRAMInitStructure.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState; + FMC_NORSRAMInitStructure.FMC_WriteOperation = FMC_WriteOperation_Enable; + FMC_NORSRAMInitStructure.FMC_WaitSignal = FMC_WaitSignal_Disable; + FMC_NORSRAMInitStructure.FMC_ExtendedMode = FMC_ExtendedMode_Disable; + FMC_NORSRAMInitStructure.FMC_WriteBurst = FMC_WriteBurst_Disable; + FMC_NORSRAMInitStructure.FMC_ContinousClock = FMC_CClock_SyncOnly; + FMC_NORSRAMInitStructure.FMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; + FMC_NORSRAMInitStructure.FMC_WriteTimingStruct = &NORSRAMTimingStructure; +*/ + +} +#endif /* DATA_IN_ExtSRAM */ + +#ifdef DATA_IN_ExtSDRAM +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external SDRAM mounted on STM324x9I_EVAL board + * This SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register uint32_t index; + + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001FC; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] = 0x0000000c; + GPIOC->AFR[1] = 0x00007700; + /* Configure PCx pins in Alternate function mode */ + GPIOC->MODER = 0x00a00002; + /* Configure PCx pins speed to 50 MHz */ + GPIOC->OSPEEDR = 0x00a00002; + /* Configure PCx pins Output type to push-pull */ + GPIOC->OTYPER = 0x00000000; + /* No pull-up, pull-down for PCx pins */ + GPIOC->PUPDR = 0x00500000; + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xcccccccc; + GPIOF->AFR[1] = 0xcccccccc; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xcccccccc; + GPIOG->AFR[1] = 0xcccccccc; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xaaaaaaaa; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xaaaaaaaa; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + +/*-- FMC Configuration ------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + + /* Configure and enable SDRAM bank1 */ + FMC_Bank5_6->SDCR[0] = 0x000039D0; + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + +/* + Bank1_SDRAM is configured as follow: + + FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2; + FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 6; + FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4; + FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 6; + FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2; + FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2; + FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2; + + FMC_SDRAMInitStructure.FMC_Bank = SDRAM_BANK; + FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b; + FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_11b; + FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b; + FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; + FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3; + FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; + FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2; + FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_disable; + FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1; + FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure; +*/ + +} +#endif /* DATA_IN_ExtSDRAM */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/APP/system_stm32f4xx.h b/APP/system_stm32f4xx.h new file mode 100644 index 0000000..d064cb4 --- /dev/null +++ b/APP/system_stm32f4xx.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/CMSIS/core_cm4.h b/CMSIS/core_cm4.h new file mode 100644 index 0000000..d65016c --- /dev/null +++ b/CMSIS/core_cm4.h @@ -0,0 +1,1772 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/CMSIS/core_cm4_simd.h b/CMSIS/core_cm4_simd.h new file mode 100644 index 0000000..83db95b --- /dev/null +++ b/CMSIS/core_cm4_simd.h @@ -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 + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#include + +/*-- 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 diff --git a/CMSIS/core_cmFunc.h b/CMSIS/core_cmFunc.h new file mode 100644 index 0000000..0a18faf --- /dev/null +++ b/CMSIS/core_cmFunc.h @@ -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 + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#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 */ diff --git a/CMSIS/core_cmInstr.h b/CMSIS/core_cmInstr.h new file mode 100644 index 0000000..d213f0e --- /dev/null +++ b/CMSIS/core_cmInstr.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 + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#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 */ diff --git a/DRIVER/inc/misc.h b/DRIVER/inc/misc.h new file mode 100644 index 0000000..6c2fa6a --- /dev/null +++ b/DRIVER/inc/misc.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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/inc/stm32f4xx_exti.h b/DRIVER/inc/stm32f4xx_exti.h new file mode 100644 index 0000000..15eea48 --- /dev/null +++ b/DRIVER/inc/stm32f4xx_exti.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/inc/stm32f4xx_gpio.h b/DRIVER/inc/stm32f4xx_gpio.h new file mode 100644 index 0000000..e41bf4e --- /dev/null +++ b/DRIVER/inc/stm32f4xx_gpio.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/inc/stm32f4xx_rcc.h b/DRIVER/inc/stm32f4xx_rcc.h new file mode 100644 index 0000000..2a77e33 --- /dev/null +++ b/DRIVER/inc/stm32f4xx_rcc.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/inc/stm32f4xx_syscfg.h b/DRIVER/inc/stm32f4xx_syscfg.h new file mode 100644 index 0000000..efbf5b2 --- /dev/null +++ b/DRIVER/inc/stm32f4xx_syscfg.h @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/inc/stm32f4xx_tim.h b/DRIVER/inc/stm32f4xx_tim.h new file mode 100644 index 0000000..a7b1db6 --- /dev/null +++ b/DRIVER/inc/stm32f4xx_tim.h @@ -0,0 +1,1150 @@ +/** + ****************************************************************************** + * @file stm32f4xx_tim.h + * @author MCD Application Team + * @version V1.4.0 + * @date 04-August-2014 + * @brief This file contains all the functions prototypes for the TIM firmware + * library. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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_TIM_H +#define __STM32F4xx_TIM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief TIM Time Base Init structure definition + * @note This structure is used with all TIMx except for TIM6 and TIM7. + */ + +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between 0x0000 and 0xFFFF. */ + + uint16_t TIM_ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_Clock_Division_CKD */ + + uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + This parameter must be a number between 0x00 and 0xFF. + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ + +typedef struct +{ + uint16_t TIM_OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_State */ + + uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_Output_Compare_N_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between 0x0000 and 0xFFFF */ + + uint16_t TIM_OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ + +typedef struct +{ + + uint16_t TIM_Channel; /*!< Specifies the TIM channel. + This parameter can be a value of @ref TIM_Channel */ + + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint16_t TIM_ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between 0x0 and 0xF */ +} TIM_ICInitTypeDef; + +/** + * @brief BDTR structure definition + * @note This structure is used only with TIM1 and TIM8. + */ + +typedef struct +{ + + uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_Lock_level */ + + uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between 0x00 and 0xFF */ + + uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + + uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_Break_Polarity */ + + uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ +} TIM_BDTRInitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_constants + * @{ + */ + +#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + (((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14))) +/* LIST1: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM10, TIM11, TIM12, TIM13 and TIM14 */ +#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM10) || \ + ((PERIPH) == TIM11) || \ + ((PERIPH) == TIM12) || \ + ((PERIPH) == TIM13) || \ + ((PERIPH) == TIM14)) + +/* LIST2: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9 and TIM12 */ +#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8) || \ + ((PERIPH) == TIM9) || \ + ((PERIPH) == TIM12)) +/* LIST3: TIM1, TIM2, TIM3, TIM4, TIM5 and TIM8 */ +#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM8)) +/* LIST4: TIM1 and TIM8 */ +#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM8)) +/* LIST5: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM8 */ +#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \ + ((PERIPH) == TIM2) || \ + ((PERIPH) == TIM3) || \ + ((PERIPH) == TIM4) || \ + ((PERIPH) == TIM5) || \ + ((PERIPH) == TIM6) || \ + ((PERIPH) == TIM7) || \ + ((PERIPH) == TIM8)) +/* LIST6: TIM2, TIM5 and TIM11 */ +#define IS_TIM_LIST6_PERIPH(TIMx)(((TIMx) == TIM2) || \ + ((TIMx) == TIM5) || \ + ((TIMx) == TIM11)) + +/** @defgroup TIM_Output_Compare_and_PWM_modes + * @{ + */ + +#define TIM_OCMode_Timing ((uint16_t)0x0000) +#define TIM_OCMode_Active ((uint16_t)0x0010) +#define TIM_OCMode_Inactive ((uint16_t)0x0020) +#define TIM_OCMode_Toggle ((uint16_t)0x0030) +#define TIM_OCMode_PWM1 ((uint16_t)0x0060) +#define TIM_OCMode_PWM2 ((uint16_t)0x0070) +#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2)) +#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \ + ((MODE) == TIM_OCMode_Active) || \ + ((MODE) == TIM_OCMode_Inactive) || \ + ((MODE) == TIM_OCMode_Toggle)|| \ + ((MODE) == TIM_OCMode_PWM1) || \ + ((MODE) == TIM_OCMode_PWM2) || \ + ((MODE) == TIM_ForcedAction_Active) || \ + ((MODE) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode + * @{ + */ + +#define TIM_OPMode_Single ((uint16_t)0x0008) +#define TIM_OPMode_Repetitive ((uint16_t)0x0000) +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \ + ((MODE) == TIM_OPMode_Repetitive)) +/** + * @} + */ + +/** @defgroup TIM_Channel + * @{ + */ + +#define TIM_Channel_1 ((uint16_t)0x0000) +#define TIM_Channel_2 ((uint16_t)0x0004) +#define TIM_Channel_3 ((uint16_t)0x0008) +#define TIM_Channel_4 ((uint16_t)0x000C) + +#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3) || \ + ((CHANNEL) == TIM_Channel_4)) + +#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2)) +#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \ + ((CHANNEL) == TIM_Channel_2) || \ + ((CHANNEL) == TIM_Channel_3)) +/** + * @} + */ + +/** @defgroup TIM_Clock_Division_CKD + * @{ + */ + +#define TIM_CKD_DIV1 ((uint16_t)0x0000) +#define TIM_CKD_DIV2 ((uint16_t)0x0100) +#define TIM_CKD_DIV4 ((uint16_t)0x0200) +#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \ + ((DIV) == TIM_CKD_DIV2) || \ + ((DIV) == TIM_CKD_DIV4)) +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode + * @{ + */ + +#define TIM_CounterMode_Up ((uint16_t)0x0000) +#define TIM_CounterMode_Down ((uint16_t)0x0010) +#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) +#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) +#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) +#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \ + ((MODE) == TIM_CounterMode_Down) || \ + ((MODE) == TIM_CounterMode_CenterAligned1) || \ + ((MODE) == TIM_CounterMode_CenterAligned2) || \ + ((MODE) == TIM_CounterMode_CenterAligned3)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity + * @{ + */ + +#define TIM_OCPolarity_High ((uint16_t)0x0000) +#define TIM_OCPolarity_Low ((uint16_t)0x0002) +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \ + ((POLARITY) == TIM_OCPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity + * @{ + */ + +#define TIM_OCNPolarity_High ((uint16_t)0x0000) +#define TIM_OCNPolarity_Low ((uint16_t)0x0008) +#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \ + ((POLARITY) == TIM_OCNPolarity_Low)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State + * @{ + */ + +#define TIM_OutputState_Disable ((uint16_t)0x0000) +#define TIM_OutputState_Enable ((uint16_t)0x0001) +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \ + ((STATE) == TIM_OutputState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State + * @{ + */ + +#define TIM_OutputNState_Disable ((uint16_t)0x0000) +#define TIM_OutputNState_Enable ((uint16_t)0x0004) +#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \ + ((STATE) == TIM_OutputNState_Enable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_State + * @{ + */ + +#define TIM_CCx_Enable ((uint16_t)0x0001) +#define TIM_CCx_Disable ((uint16_t)0x0000) +#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \ + ((CCX) == TIM_CCx_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Capture_Compare_N_State + * @{ + */ + +#define TIM_CCxN_Enable ((uint16_t)0x0004) +#define TIM_CCxN_Disable ((uint16_t)0x0000) +#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \ + ((CCXN) == TIM_CCxN_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable + * @{ + */ + +#define TIM_Break_Enable ((uint16_t)0x1000) +#define TIM_Break_Disable ((uint16_t)0x0000) +#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \ + ((STATE) == TIM_Break_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity + * @{ + */ + +#define TIM_BreakPolarity_Low ((uint16_t)0x0000) +#define TIM_BreakPolarity_High ((uint16_t)0x2000) +#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \ + ((POLARITY) == TIM_BreakPolarity_High)) +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset + * @{ + */ + +#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000) +#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000) +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \ + ((STATE) == TIM_AutomaticOutput_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Lock_level + * @{ + */ + +#define TIM_LOCKLevel_OFF ((uint16_t)0x0000) +#define TIM_LOCKLevel_1 ((uint16_t)0x0100) +#define TIM_LOCKLevel_2 ((uint16_t)0x0200) +#define TIM_LOCKLevel_3 ((uint16_t)0x0300) +#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \ + ((LEVEL) == TIM_LOCKLevel_1) || \ + ((LEVEL) == TIM_LOCKLevel_2) || \ + ((LEVEL) == TIM_LOCKLevel_3)) +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state + * @{ + */ + +#define TIM_OSSIState_Enable ((uint16_t)0x0400) +#define TIM_OSSIState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \ + ((STATE) == TIM_OSSIState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state + * @{ + */ + +#define TIM_OSSRState_Enable ((uint16_t)0x0800) +#define TIM_OSSRState_Disable ((uint16_t)0x0000) +#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \ + ((STATE) == TIM_OSSRState_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State + * @{ + */ + +#define TIM_OCIdleState_Set ((uint16_t)0x0100) +#define TIM_OCIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \ + ((STATE) == TIM_OCIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State + * @{ + */ + +#define TIM_OCNIdleState_Set ((uint16_t)0x0200) +#define TIM_OCNIdleState_Reset ((uint16_t)0x0000) +#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \ + ((STATE) == TIM_OCNIdleState_Reset)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity + * @{ + */ + +#define TIM_ICPolarity_Rising ((uint16_t)0x0000) +#define TIM_ICPolarity_Falling ((uint16_t)0x0002) +#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A) +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \ + ((POLARITY) == TIM_ICPolarity_Falling)|| \ + ((POLARITY) == TIM_ICPolarity_BothEdge)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection + * @{ + */ + +#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively. */ +#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */ +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \ + ((SELECTION) == TIM_ICSelection_IndirectTI) || \ + ((SELECTION) == TIM_ICSelection_TRC)) +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler + * @{ + */ + +#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */ +#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */ +#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */ +#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */ +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_interrupt_sources + * @{ + */ + +#define TIM_IT_Update ((uint16_t)0x0001) +#define TIM_IT_CC1 ((uint16_t)0x0002) +#define TIM_IT_CC2 ((uint16_t)0x0004) +#define TIM_IT_CC3 ((uint16_t)0x0008) +#define TIM_IT_CC4 ((uint16_t)0x0010) +#define TIM_IT_COM ((uint16_t)0x0020) +#define TIM_IT_Trigger ((uint16_t)0x0040) +#define TIM_IT_Break ((uint16_t)0x0080) +#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000)) + +#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \ + ((IT) == TIM_IT_CC1) || \ + ((IT) == TIM_IT_CC2) || \ + ((IT) == TIM_IT_CC3) || \ + ((IT) == TIM_IT_CC4) || \ + ((IT) == TIM_IT_COM) || \ + ((IT) == TIM_IT_Trigger) || \ + ((IT) == TIM_IT_Break)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address + * @{ + */ + +#define TIM_DMABase_CR1 ((uint16_t)0x0000) +#define TIM_DMABase_CR2 ((uint16_t)0x0001) +#define TIM_DMABase_SMCR ((uint16_t)0x0002) +#define TIM_DMABase_DIER ((uint16_t)0x0003) +#define TIM_DMABase_SR ((uint16_t)0x0004) +#define TIM_DMABase_EGR ((uint16_t)0x0005) +#define TIM_DMABase_CCMR1 ((uint16_t)0x0006) +#define TIM_DMABase_CCMR2 ((uint16_t)0x0007) +#define TIM_DMABase_CCER ((uint16_t)0x0008) +#define TIM_DMABase_CNT ((uint16_t)0x0009) +#define TIM_DMABase_PSC ((uint16_t)0x000A) +#define TIM_DMABase_ARR ((uint16_t)0x000B) +#define TIM_DMABase_RCR ((uint16_t)0x000C) +#define TIM_DMABase_CCR1 ((uint16_t)0x000D) +#define TIM_DMABase_CCR2 ((uint16_t)0x000E) +#define TIM_DMABase_CCR3 ((uint16_t)0x000F) +#define TIM_DMABase_CCR4 ((uint16_t)0x0010) +#define TIM_DMABase_BDTR ((uint16_t)0x0011) +#define TIM_DMABase_DCR ((uint16_t)0x0012) +#define TIM_DMABase_OR ((uint16_t)0x0013) +#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \ + ((BASE) == TIM_DMABase_CR2) || \ + ((BASE) == TIM_DMABase_SMCR) || \ + ((BASE) == TIM_DMABase_DIER) || \ + ((BASE) == TIM_DMABase_SR) || \ + ((BASE) == TIM_DMABase_EGR) || \ + ((BASE) == TIM_DMABase_CCMR1) || \ + ((BASE) == TIM_DMABase_CCMR2) || \ + ((BASE) == TIM_DMABase_CCER) || \ + ((BASE) == TIM_DMABase_CNT) || \ + ((BASE) == TIM_DMABase_PSC) || \ + ((BASE) == TIM_DMABase_ARR) || \ + ((BASE) == TIM_DMABase_RCR) || \ + ((BASE) == TIM_DMABase_CCR1) || \ + ((BASE) == TIM_DMABase_CCR2) || \ + ((BASE) == TIM_DMABase_CCR3) || \ + ((BASE) == TIM_DMABase_CCR4) || \ + ((BASE) == TIM_DMABase_BDTR) || \ + ((BASE) == TIM_DMABase_DCR) || \ + ((BASE) == TIM_DMABase_OR)) +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length + * @{ + */ + +#define TIM_DMABurstLength_1Transfer ((uint16_t)0x0000) +#define TIM_DMABurstLength_2Transfers ((uint16_t)0x0100) +#define TIM_DMABurstLength_3Transfers ((uint16_t)0x0200) +#define TIM_DMABurstLength_4Transfers ((uint16_t)0x0300) +#define TIM_DMABurstLength_5Transfers ((uint16_t)0x0400) +#define TIM_DMABurstLength_6Transfers ((uint16_t)0x0500) +#define TIM_DMABurstLength_7Transfers ((uint16_t)0x0600) +#define TIM_DMABurstLength_8Transfers ((uint16_t)0x0700) +#define TIM_DMABurstLength_9Transfers ((uint16_t)0x0800) +#define TIM_DMABurstLength_10Transfers ((uint16_t)0x0900) +#define TIM_DMABurstLength_11Transfers ((uint16_t)0x0A00) +#define TIM_DMABurstLength_12Transfers ((uint16_t)0x0B00) +#define TIM_DMABurstLength_13Transfers ((uint16_t)0x0C00) +#define TIM_DMABurstLength_14Transfers ((uint16_t)0x0D00) +#define TIM_DMABurstLength_15Transfers ((uint16_t)0x0E00) +#define TIM_DMABurstLength_16Transfers ((uint16_t)0x0F00) +#define TIM_DMABurstLength_17Transfers ((uint16_t)0x1000) +#define TIM_DMABurstLength_18Transfers ((uint16_t)0x1100) +#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Transfer) || \ + ((LENGTH) == TIM_DMABurstLength_2Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_3Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_4Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_5Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_6Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_7Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_8Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_9Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_10Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_11Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_12Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_13Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_14Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_15Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_16Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_17Transfers) || \ + ((LENGTH) == TIM_DMABurstLength_18Transfers)) +/** + * @} + */ + +/** @defgroup TIM_DMA_sources + * @{ + */ + +#define TIM_DMA_Update ((uint16_t)0x0100) +#define TIM_DMA_CC1 ((uint16_t)0x0200) +#define TIM_DMA_CC2 ((uint16_t)0x0400) +#define TIM_DMA_CC3 ((uint16_t)0x0800) +#define TIM_DMA_CC4 ((uint16_t)0x1000) +#define TIM_DMA_COM ((uint16_t)0x2000) +#define TIM_DMA_Trigger ((uint16_t)0x4000) +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000) +#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000) +#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000) +#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000) +#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \ + ((PRESCALER) == TIM_ExtTRGPSC_DIV8)) +/** + * @} + */ + +/** @defgroup TIM_Internal_Trigger_Selection + * @{ + */ + +#define TIM_TS_ITR0 ((uint16_t)0x0000) +#define TIM_TS_ITR1 ((uint16_t)0x0010) +#define TIM_TS_ITR2 ((uint16_t)0x0020) +#define TIM_TS_ITR3 ((uint16_t)0x0030) +#define TIM_TS_TI1F_ED ((uint16_t)0x0040) +#define TIM_TS_TI1FP1 ((uint16_t)0x0050) +#define TIM_TS_TI2FP2 ((uint16_t)0x0060) +#define TIM_TS_ETRF ((uint16_t)0x0070) +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_TI1F_ED) || \ + ((SELECTION) == TIM_TS_TI1FP1) || \ + ((SELECTION) == TIM_TS_TI2FP2) || \ + ((SELECTION) == TIM_TS_ETRF)) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) +/** + * @} + */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ + +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) + +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000) +#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000) +#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \ + ((POLARITY) == TIM_ExtTRGPolarity_NonInverted)) +/** + * @} + */ + +/** @defgroup TIM_Prescaler_Reload_Mode + * @{ + */ + +#define TIM_PSCReloadMode_Update ((uint16_t)0x0000) +#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001) +#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \ + ((RELOAD) == TIM_PSCReloadMode_Immediate)) +/** + * @} + */ + +/** @defgroup TIM_Forced_Action + * @{ + */ + +#define TIM_ForcedAction_Active ((uint16_t)0x0050) +#define TIM_ForcedAction_InActive ((uint16_t)0x0040) +#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \ + ((ACTION) == TIM_ForcedAction_InActive)) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode + * @{ + */ + +#define TIM_EncoderMode_TI1 ((uint16_t)0x0001) +#define TIM_EncoderMode_TI2 ((uint16_t)0x0002) +#define TIM_EncoderMode_TI12 ((uint16_t)0x0003) +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \ + ((MODE) == TIM_EncoderMode_TI2) || \ + ((MODE) == TIM_EncoderMode_TI12)) +/** + * @} + */ + + +/** @defgroup TIM_Event_Source + * @{ + */ + +#define TIM_EventSource_Update ((uint16_t)0x0001) +#define TIM_EventSource_CC1 ((uint16_t)0x0002) +#define TIM_EventSource_CC2 ((uint16_t)0x0004) +#define TIM_EventSource_CC3 ((uint16_t)0x0008) +#define TIM_EventSource_CC4 ((uint16_t)0x0010) +#define TIM_EventSource_COM ((uint16_t)0x0020) +#define TIM_EventSource_Trigger ((uint16_t)0x0040) +#define TIM_EventSource_Break ((uint16_t)0x0080) +#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000)) + +/** + * @} + */ + +/** @defgroup TIM_Update_Source + * @{ + */ + +#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ +#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */ +#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \ + ((SOURCE) == TIM_UpdateSource_Regular)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Preload_State + * @{ + */ + +#define TIM_OCPreload_Enable ((uint16_t)0x0008) +#define TIM_OCPreload_Disable ((uint16_t)0x0000) +#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \ + ((STATE) == TIM_OCPreload_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Fast_State + * @{ + */ + +#define TIM_OCFast_Enable ((uint16_t)0x0004) +#define TIM_OCFast_Disable ((uint16_t)0x0000) +#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \ + ((STATE) == TIM_OCFast_Disable)) + +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Clear_State + * @{ + */ + +#define TIM_OCClear_Enable ((uint16_t)0x0080) +#define TIM_OCClear_Disable ((uint16_t)0x0000) +#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \ + ((STATE) == TIM_OCClear_Disable)) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Output_Source + * @{ + */ + +#define TIM_TRGOSource_Reset ((uint16_t)0x0000) +#define TIM_TRGOSource_Enable ((uint16_t)0x0010) +#define TIM_TRGOSource_Update ((uint16_t)0x0020) +#define TIM_TRGOSource_OC1 ((uint16_t)0x0030) +#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040) +#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050) +#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060) +#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070) +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \ + ((SOURCE) == TIM_TRGOSource_Enable) || \ + ((SOURCE) == TIM_TRGOSource_Update) || \ + ((SOURCE) == TIM_TRGOSource_OC1) || \ + ((SOURCE) == TIM_TRGOSource_OC1Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC2Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC3Ref) || \ + ((SOURCE) == TIM_TRGOSource_OC4Ref)) +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode + * @{ + */ + +#define TIM_SlaveMode_Reset ((uint16_t)0x0004) +#define TIM_SlaveMode_Gated ((uint16_t)0x0005) +#define TIM_SlaveMode_Trigger ((uint16_t)0x0006) +#define TIM_SlaveMode_External1 ((uint16_t)0x0007) +#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \ + ((MODE) == TIM_SlaveMode_Gated) || \ + ((MODE) == TIM_SlaveMode_Trigger) || \ + ((MODE) == TIM_SlaveMode_External1)) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode + * @{ + */ + +#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080) +#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000) +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \ + ((STATE) == TIM_MasterSlaveMode_Disable)) +/** + * @} + */ +/** @defgroup TIM_Remap + * @{ + */ + +#define TIM2_TIM8_TRGO ((uint16_t)0x0000) +#define TIM2_ETH_PTP ((uint16_t)0x0400) +#define TIM2_USBFS_SOF ((uint16_t)0x0800) +#define TIM2_USBHS_SOF ((uint16_t)0x0C00) + +#define TIM5_GPIO ((uint16_t)0x0000) +#define TIM5_LSI ((uint16_t)0x0040) +#define TIM5_LSE ((uint16_t)0x0080) +#define TIM5_RTC ((uint16_t)0x00C0) + +#define TIM11_GPIO ((uint16_t)0x0000) +#define TIM11_HSE ((uint16_t)0x0002) + +#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_TIM8_TRGO)||\ + ((TIM_REMAP) == TIM2_ETH_PTP)||\ + ((TIM_REMAP) == TIM2_USBFS_SOF)||\ + ((TIM_REMAP) == TIM2_USBHS_SOF)||\ + ((TIM_REMAP) == TIM5_GPIO)||\ + ((TIM_REMAP) == TIM5_LSI)||\ + ((TIM_REMAP) == TIM5_LSE)||\ + ((TIM_REMAP) == TIM5_RTC)||\ + ((TIM_REMAP) == TIM11_GPIO)||\ + ((TIM_REMAP) == TIM11_HSE)) + +/** + * @} + */ +/** @defgroup TIM_Flags + * @{ + */ + +#define TIM_FLAG_Update ((uint16_t)0x0001) +#define TIM_FLAG_CC1 ((uint16_t)0x0002) +#define TIM_FLAG_CC2 ((uint16_t)0x0004) +#define TIM_FLAG_CC3 ((uint16_t)0x0008) +#define TIM_FLAG_CC4 ((uint16_t)0x0010) +#define TIM_FLAG_COM ((uint16_t)0x0020) +#define TIM_FLAG_Trigger ((uint16_t)0x0040) +#define TIM_FLAG_Break ((uint16_t)0x0080) +#define TIM_FLAG_CC1OF ((uint16_t)0x0200) +#define TIM_FLAG_CC2OF ((uint16_t)0x0400) +#define TIM_FLAG_CC3OF ((uint16_t)0x0800) +#define TIM_FLAG_CC4OF ((uint16_t)0x1000) +#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \ + ((FLAG) == TIM_FLAG_CC1) || \ + ((FLAG) == TIM_FLAG_CC2) || \ + ((FLAG) == TIM_FLAG_CC3) || \ + ((FLAG) == TIM_FLAG_CC4) || \ + ((FLAG) == TIM_FLAG_COM) || \ + ((FLAG) == TIM_FLAG_Trigger) || \ + ((FLAG) == TIM_FLAG_Break) || \ + ((FLAG) == TIM_FLAG_CC1OF) || \ + ((FLAG) == TIM_FLAG_CC2OF) || \ + ((FLAG) == TIM_FLAG_CC3OF) || \ + ((FLAG) == TIM_FLAG_CC4OF)) + +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Filer_Value + * @{ + */ + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_External_Trigger_Filter + * @{ + */ + +#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_Legacy + * @{ + */ + +#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer +#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers +#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers +#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers +#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers +#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers +#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers +#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers +#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers +#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers +#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers +#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers +#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers +#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers +#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers +#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers +#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers +#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* TimeBase management ********************************************************/ +void TIM_DeInit(TIM_TypeDef* TIMx); +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode); +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter); +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload); +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx); +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx); +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource); +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode); +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD); +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Output Compare management **************************************************/ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1); +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2); +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3); +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4); +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx); +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); + +/* Input Capture management ***************************************************/ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx); +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx); +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); + +/* Advanced-control timers (TIM1 and TIM8) specific features ******************/ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct); +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState); +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Interrupts, DMA and flags management ***************************************/ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource); +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength); +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState); +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Clocks management **********************************************************/ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx); +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); + +/* Synchronization management *************************************************/ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); + +/* Specific interface management **********************************************/ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity); +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState); + +/* Specific remapping management **********************************************/ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_TIM_H */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/DRIVER/src/misc.c b/DRIVER/src/misc.c new file mode 100644 index 0000000..dc7d808 --- /dev/null +++ b/DRIVER/src/misc.c @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/src/stm32f4xx_exti.c b/DRIVER/src/stm32f4xx_exti.c new file mode 100644 index 0000000..433a8bf --- /dev/null +++ b/DRIVER/src/stm32f4xx_exti.c @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/src/stm32f4xx_gpio.c b/DRIVER/src/stm32f4xx_gpio.c new file mode 100644 index 0000000..0523e50 --- /dev/null +++ b/DRIVER/src/stm32f4xx_gpio.c @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/src/stm32f4xx_rcc.c b/DRIVER/src/stm32f4xx_rcc.c new file mode 100644 index 0000000..7082975 --- /dev/null +++ b/DRIVER/src/stm32f4xx_rcc.c @@ -0,0 +1,2307 @@ +/** + ****************************************************************************** + * @file stm32f4xx_rcc.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 Reset and clock control (RCC) peripheral: + * + Internal/external clocks, PLL, CSS and MCO configuration + * + System, AHB and APB busses clocks configuration + * + Peripheral clocks configuration + * + Interrupts and flags management + * + @verbatim + =============================================================================== + ##### RCC specific features ##### + =============================================================================== + [..] + After reset the device is running from Internal High Speed oscillator + (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache + and I-Cache are disabled, and all peripherals are off except internal + SRAM, Flash and JTAG. + (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses; + all peripherals mapped on these busses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in input floating state, except the JTAG pins which + are assigned to be used for debug purpose. + [..] + Once the device started from reset, the user application has to: + (+) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (+) Configure the System clock frequency and Flash settings + (+) Configure the AHB and APB busses prescalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock source(s) for peripherals which clocks are not + derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG) + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup RCC + * @brief RCC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* ------------ RCC registers bit address in the alias region ----------- */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +/* --- CR Register ---*/ +/* Alias word address of HSION bit */ +#define CR_OFFSET (RCC_OFFSET + 0x00) +#define HSION_BitNumber 0x00 +#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4)) +/* Alias word address of CSSON bit */ +#define CSSON_BitNumber 0x13 +#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4)) +/* Alias word address of PLLON bit */ +#define PLLON_BitNumber 0x18 +#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4)) +/* Alias word address of PLLI2SON bit */ +#define PLLI2SON_BitNumber 0x1A +#define CR_PLLI2SON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLI2SON_BitNumber * 4)) + +/* Alias word address of PLLSAION bit */ +#define PLLSAION_BitNumber 0x1C +#define CR_PLLSAION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLSAION_BitNumber * 4)) + +/* --- CFGR Register ---*/ +/* Alias word address of I2SSRC bit */ +#define CFGR_OFFSET (RCC_OFFSET + 0x08) +#define I2SSRC_BitNumber 0x17 +#define CFGR_I2SSRC_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (I2SSRC_BitNumber * 4)) + +/* --- BDCR Register ---*/ +/* Alias word address of RTCEN bit */ +#define BDCR_OFFSET (RCC_OFFSET + 0x70) +#define RTCEN_BitNumber 0x0F +#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4)) +/* Alias word address of BDRST bit */ +#define BDRST_BitNumber 0x10 +#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4)) + +/* --- CSR Register ---*/ +/* Alias word address of LSION bit */ +#define CSR_OFFSET (RCC_OFFSET + 0x74) +#define LSION_BitNumber 0x00 +#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4)) + +/* --- DCKCFGR Register ---*/ +/* Alias word address of TIMPRE bit */ +#define DCKCFGR_OFFSET (RCC_OFFSET + 0x8C) +#define TIMPRE_BitNumber 0x18 +#define DCKCFGR_TIMPRE_BB (PERIPH_BB_BASE + (DCKCFGR_OFFSET * 32) + (TIMPRE_BitNumber * 4)) +/* ---------------------- RCC registers bit mask ------------------------ */ +/* CFGR register bit mask */ +#define CFGR_MCO2_RESET_MASK ((uint32_t)0x07FFFFFF) +#define CFGR_MCO1_RESET_MASK ((uint32_t)0xF89FFFFF) + +/* RCC Flag Mask */ +#define FLAG_MASK ((uint8_t)0x1F) + +/* CR register byte 3 (Bits[23:16]) base address */ +#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802) + +/* CIR register byte 2 (Bits[15:8]) base address */ +#define CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x01)) + +/* CIR register byte 3 (Bits[23:16]) base address */ +#define CIR_BYTE3_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x02)) + +/* BDCR register base address */ +#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Private_Functions + * @{ + */ + +/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions + * @brief Internal and external clocks, PLL, CSS and MCO configuration functions + * +@verbatim + =================================================================================== + ##### Internal and external clocks, PLL, CSS and MCO configuration functions ##### + =================================================================================== + [..] + This section provide functions allowing to configure the internal/external clocks, + PLLs, CSS and MCO pins. + + (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + + (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (#) HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also as RTC clock source. + + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + (#) PLL (clocked by HSI or HSE), featuring two different output clocks: + (++) The first output is used to generate the high speed system clock (up to 168 MHz) + (++) The second output is used to generate the clock for the USB OTG FS (48 MHz), + the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz). + + (#) PLLI2S (clocked by HSI or HSE), used to generate an accurate clock to achieve + high-quality audio performance on the I2S interface or SAI interface in case + of STM32F429x/439x devices. + + (#) PLLSAI clocked by (HSI or HSE), used to generate an accurate clock to SAI + interface and LCD TFT controller available only for STM32F42xxx/43xxx devices. + + (#) CSS (Clock security system), once enable and if a HSE clock failure occurs + (HSE used directly or through PLL as System clock source), the System clock + is automatically switched to HSI and an interrupt is generated if enabled. + The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt) + exception vector. + + (#) MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + clock (through a configurable prescaler) on PA8 pin. + + (#) MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S + clock (through a configurable prescaler) on PC9 pin. + @endverbatim + * @{ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE, PLL and PLLI2S OFF + * - AHB, APB1 and APB2 prescaler set to 1. + * - CSS, MCO1 and MCO2 OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @param None + * @retval None + */ +void RCC_DeInit(void) +{ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON, PLLON, PLLI2S and PLLSAI(STM32F42/43xxx devices) bits */ + RCC->CR &= (uint32_t)0xEAF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset PLLI2SCFGR register */ + RCC->PLLI2SCFGR = 0x20003000; + + /* Reset PLLSAICFGR register, only available for STM32F42/43xxx devices */ + RCC->PLLSAICFGR = 0x24003000; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + + /* Disable Timers clock prescalers selection, only available for STM32F42/43xxx devices */ + RCC->DCKCFGR = 0x00000000; +} + +/** + * @brief Configures the External High Speed oscillator (HSE). + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the Clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param RCC_HSE: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg RCC_HSE_ON: turn ON the HSE oscillator + * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock + * @retval None + */ +void RCC_HSEConfig(uint8_t RCC_HSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_HSE)); + + /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF; + + /* Set the new HSE configuration -------------------------------------------*/ + *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE; +} + +/** + * @brief Waits for HSE start-up. + * @note This functions waits on HSERDY flag to be set and return SUCCESS if + * this flag is set, otherwise returns ERROR if the timeout is reached + * and this flag is not set. The timeout value is defined by the constant + * HSE_STARTUP_TIMEOUT in stm32f4xx.h file. You can tailor it depending + * on the HSE crystal used in your application. + * @param None + * @retval An ErrorStatus enumeration value: + * - SUCCESS: HSE oscillator is stable and ready to use + * - ERROR: HSE oscillator not yet ready + */ +ErrorStatus RCC_WaitForHSEStartUp(void) +{ + __IO uint32_t startupcounter = 0; + ErrorStatus status = ERROR; + FlagStatus hsestatus = RESET; + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY); + startupcounter++; + } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET)); + + if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) + { + status = SUCCESS; + } + else + { + status = ERROR; + } + return (status); +} + +/** + * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param HSICalibrationValue: specifies the calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + * @retval None + */ +void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) +{ + uint32_t tmpreg = 0; + /* Check the parameters */ + assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue)); + + tmpreg = RCC->CR; + + /* Clear HSITRIM[4:0] bits */ + tmpreg &= ~RCC_CR_HSITRIM; + + /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ + tmpreg |= (uint32_t)HSICalibrationValue << 3; + + /* Store the new value */ + RCC->CR = tmpreg; +} + +/** + * @brief Enables or disables the Internal High Speed oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after startup + * from Reset, wakeup from STOP and STANDBY mode, or in case of failure + * of the HSE used directly or indirectly as system clock (if the Clock + * Security System CSS is enabled). + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * @param NewState: new state of the HSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + * @retval None + */ +void RCC_HSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the External Low Speed oscillator (LSE). + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param RCC_LSE: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg RCC_LSE_ON: turn ON the LSE oscillator + * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock + * @retval None + */ +void RCC_LSEConfig(uint8_t RCC_LSE) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_LSE)); + + /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ + /* Reset LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + + /* Reset LSEBYP bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF; + + /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */ + switch (RCC_LSE) + { + case RCC_LSE_ON: + /* Set LSEON bit */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON; + break; + case RCC_LSE_Bypass: + /* Set LSEBYP and LSEON bits */ + *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON; + break; + default: + break; + } +} + +/** + * @brief Enables or disables the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + * @note LSI can not be disabled if the IWDG is running. + * @param NewState: new state of the LSI. + * This parameter can be: ENABLE or DISABLE. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + * @retval None + */ +void RCC_LSICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the main PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * + * @param RCC_PLLSource: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock entry + * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock entry + * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S. + * + * @param PLLM: specifies the division factor for PLL VCO input clock + * This parameter must be a number between 0 and 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLL jitter. + * + * @param PLLN: specifies the multiplication factor for PLL VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLP: specifies the division factor for main system clock (SYSCLK) + * This parameter must be a number in the range {2, 4, 6, or 8}. + * @note You have to set the PLLP parameter correctly to not exceed 168 MHz on + * the System clock frequency. + * + * @param PLLQ: specifies the division factor for OTG FS, SDIO and RNG clocks + * This parameter must be a number between 4 and 15. + * @note If the USB OTG FS is used in your application, you have to set the + * PLLQ parameter correctly to have 48 MHz clock for the USB. However, + * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work + * correctly. + * + * @retval None + */ +void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource)); + assert_param(IS_RCC_PLLM_VALUE(PLLM)); + assert_param(IS_RCC_PLLN_VALUE(PLLN)); + assert_param(IS_RCC_PLLP_VALUE(PLLP)); + assert_param(IS_RCC_PLLQ_VALUE(PLLQ)); + + RCC->PLLCFGR = PLLM | (PLLN << 6) | (((PLLP >> 1) -1) << 16) | (RCC_PLLSource) | + (PLLQ << 24); +} + +/** + * @brief Enables or disables the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL can not be disabled if it is used as system clock source + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the main PLL. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState; +} + +#if defined (STM32F40_41xxx) || defined (STM32F401xx) +/** + * @brief Configures the PLLI2S clock multiplication and division factors. + * + * @note This function can be used only for STM32F405xx/407xx, STM32F415xx/417xx + * or STM32F401xx devices. + * + * @note This function must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * RCC_PLLConfig function ) + * + * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLI2SR: specifies the division factor for I2S clock + * This parameter must be a number between 2 and 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * + * @retval None + */ +void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN)); + assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR)); + + RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SR << 28); +} + +#elif defined (STM32F411xE) +/** + * @brief Configures the PLLI2S clock multiplication and division factors. + * + * @note This function can be used only for STM32F411xE devices. + * + * @note This function must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * RCC_PLLConfig function ) + * + * @param PLLI2SM: specifies the division factor for PLLI2S VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLI2SM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLLI2S jitter. + * + * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLI2SR: specifies the division factor for I2S clock + * This parameter must be a number between 2 and 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * + * @retval None + */ +void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR, uint32_t PLLI2SM) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN)); + assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SM)); + assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR)); + + RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SR << 28) | PLLI2SM; +} + +#elif defined (STM32F427_437xx) || defined (STM32F429_439xx) +/** + * @brief Configures the PLLI2S clock multiplication and division factors. + * + * @note This function can be used only for STM32F42xxx/43xxx devices + * + * @note This function must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * RCC_PLLConfig function ) + * + * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLI2SQ: specifies the division factor for SAI1 clock + * This parameter must be a number between 2 and 15. + * + * @param PLLI2SR: specifies the division factor for I2S clock + * This parameter must be a number between 2 and 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * @note the PLLI2SR parameter is only available with STM32F42xxx/43xxx devices. + * + * @retval None + */ +void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SQ, uint32_t PLLI2SR) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN)); + assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SQ)); + assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR)); + + RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SQ << 24) | (PLLI2SR << 28); +} +#else +#endif /* STM32F40_41xxx || STM32F401xx */ + +/** + * @brief Enables or disables the PLLI2S. + * @note The PLLI2S is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the PLLI2S. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLI2SCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLLI2SON_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the PLLSAI clock multiplication and division factors. + * + * @note This function can be used only for STM32F42xxx/43xxx devices + * + * @note This function must be used only when the PLLSAI is disabled. + * @note PLLSAI clock source is common with the main PLL (configured in + * RCC_PLLConfig function ) + * + * @param PLLSAIN: specifies the multiplication factor for PLLSAI VCO output clock + * This parameter must be a number between 192 and 432. + * @note You have to set the PLLSAIN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param PLLSAIQ: specifies the division factor for SAI1 clock + * This parameter must be a number between 2 and 15. + * + * @param PLLSAIR: specifies the division factor for LTDC clock + * This parameter must be a number between 2 and 7. + * + * @retval None + */ +void RCC_PLLSAIConfig(uint32_t PLLSAIN, uint32_t PLLSAIQ, uint32_t PLLSAIR) +{ + /* Check the parameters */ + assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIN)); + assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIR)); + + RCC->PLLSAICFGR = (PLLSAIN << 6) | (PLLSAIQ << 24) | (PLLSAIR << 28); +} + +/** + * @brief Enables or disables the PLLSAI. + * + * @note This function can be used only for STM32F42xxx/43xxx devices + * + * @note The PLLSAI is disabled by hardware when entering STOP and STANDBY modes. + * @param NewState: new state of the PLLSAI. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PLLSAICmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_PLLSAION_BB = (uint32_t)NewState; +} + +/** + * @brief Enables or disables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. + * @param NewState: new state of the Clock Security System. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ClockSecuritySystemCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState; +} + +/** + * @brief Selects the clock source to output on MCO1 pin(PA8). + * @note PA8 should be configured in alternate function mode. + * @param RCC_MCO1Source: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO1Source_HSI: HSI clock selected as MCO1 source + * @arg RCC_MCO1Source_LSE: LSE clock selected as MCO1 source + * @arg RCC_MCO1Source_HSE: HSE clock selected as MCO1 source + * @arg RCC_MCO1Source_PLLCLK: main PLL clock selected as MCO1 source + * @param RCC_MCO1Div: specifies the MCO1 prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCO1Div_1: no division applied to MCO1 clock + * @arg RCC_MCO1Div_2: division by 2 applied to MCO1 clock + * @arg RCC_MCO1Div_3: division by 3 applied to MCO1 clock + * @arg RCC_MCO1Div_4: division by 4 applied to MCO1 clock + * @arg RCC_MCO1Div_5: division by 5 applied to MCO1 clock + * @retval None + */ +void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MCO1SOURCE(RCC_MCO1Source)); + assert_param(IS_RCC_MCO1DIV(RCC_MCO1Div)); + + tmpreg = RCC->CFGR; + + /* Clear MCO1[1:0] and MCO1PRE[2:0] bits */ + tmpreg &= CFGR_MCO1_RESET_MASK; + + /* Select MCO1 clock source and prescaler */ + tmpreg |= RCC_MCO1Source | RCC_MCO1Div; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Selects the clock source to output on MCO2 pin(PC9). + * @note PC9 should be configured in alternate function mode. + * @param RCC_MCO2Source: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO2Source_SYSCLK: System clock (SYSCLK) selected as MCO2 source + * @arg RCC_MCO2Source_PLLI2SCLK: PLLI2S clock selected as MCO2 source + * @arg RCC_MCO2Source_HSE: HSE clock selected as MCO2 source + * @arg RCC_MCO2Source_PLLCLK: main PLL clock selected as MCO2 source + * @param RCC_MCO2Div: specifies the MCO2 prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCO2Div_1: no division applied to MCO2 clock + * @arg RCC_MCO2Div_2: division by 2 applied to MCO2 clock + * @arg RCC_MCO2Div_3: division by 3 applied to MCO2 clock + * @arg RCC_MCO2Div_4: division by 4 applied to MCO2 clock + * @arg RCC_MCO2Div_5: division by 5 applied to MCO2 clock + * @retval None + */ +void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_MCO2SOURCE(RCC_MCO2Source)); + assert_param(IS_RCC_MCO2DIV(RCC_MCO2Div)); + + tmpreg = RCC->CFGR; + + /* Clear MCO2 and MCO2PRE[2:0] bits */ + tmpreg &= CFGR_MCO2_RESET_MASK; + + /* Select MCO2 clock source and prescaler */ + tmpreg |= RCC_MCO2Source | RCC_MCO2Div; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @} + */ + +/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions + * @brief System, AHB and APB busses clocks configuration functions + * +@verbatim + =============================================================================== + ##### System, AHB and APB busses clocks configuration functions ##### + =============================================================================== + [..] + This section provide functions allowing to configure the System, AHB, APB1 and + APB2 busses clocks. + + (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these busses. You can use + "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks. + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: + (+@) I2S: the I2S clock can be derived either from a specific PLL (PLLI2S) or + from an external clock mapped on the I2S_CKIN pin. + You have to use RCC_I2SCLKConfig() function to configure this clock. + (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 31. You have to use RCC_RTCCLKConfig() and RCC_RTCCLKCmd() + functions to configure this clock. + (+@) USB OTG FS, SDIO and RTC: USB OTG FS require a frequency equal to 48 MHz + to work correctly, while the SDIO require a frequency equal or lower than + to 48. This clock is derived of the main PLL through PLLQ divider. + (+@) IWDG clock which is always the LSI clock. + + (#) For STM32F405xx/407xx and STM32F415xx/417xx devices, the maximum frequency + of the SYSCLK and HCLK is 168 MHz, PCLK2 84 MHz and PCLK1 42 MHz. Depending + on the device voltage range, the maximum frequency should be adapted accordingly: + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 22 |0 < HCLK <= 20 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |22 < HCLK <= 44 |20 < HCLK <= 40 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |44 < HCLK <= 66 |40 < HCLK <= 60 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |66 < HCLK <= 88 |60 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)|120< HCLK <= 150|96 < HCLK <= 120|88 < HCLK <= 110 |80 < HCLK <= 100 | + |---------------|----------------|----------------|-----------------|-----------------| + |5WS(6CPU cycle)|150< HCLK <= 168|120< HCLK <= 144|110 < HCLK <= 132|100 < HCLK <= 120| + |---------------|----------------|----------------|-----------------|-----------------| + |6WS(7CPU cycle)| NA |144< HCLK <= 168|132 < HCLK <= 154|120 < HCLK <= 140| + |---------------|----------------|----------------|-----------------|-----------------| + |7WS(8CPU cycle)| NA | NA |154 < HCLK <= 168|140 < HCLK <= 160| + +---------------|----------------|----------------|-----------------|-----------------+ + (#) For STM32F42xxx/43xxx devices, the maximum frequency of the SYSCLK and HCLK is 180 MHz, + PCLK2 90 MHz and PCLK1 45 MHz. Depending on the device voltage range, the maximum + frequency should be adapted accordingly: + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 22 |0 < HCLK <= 20 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |22 < HCLK <= 44 |20 < HCLK <= 40 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |44 < HCLK <= 66 |40 < HCLK <= 60 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |66 < HCLK <= 88 |60 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)|120< HCLK <= 150|96 < HCLK <= 120|88 < HCLK <= 110 |80 < HCLK <= 100 | + |---------------|----------------|----------------|-----------------|-----------------| + |5WS(6CPU cycle)|120< HCLK <= 180|120< HCLK <= 144|110 < HCLK <= 132|100 < HCLK <= 120| + |---------------|----------------|----------------|-----------------|-----------------| + |6WS(7CPU cycle)| NA |144< HCLK <= 168|132 < HCLK <= 154|120 < HCLK <= 140| + |---------------|----------------|----------------|-----------------|-----------------| + |7WS(8CPU cycle)| NA |168< HCLK <= 180|154 < HCLK <= 176|140 < HCLK <= 160| + |---------------|----------------|----------------|-----------------|-----------------| + |8WS(9CPU cycle)| NA | NA |176 < HCLK <= 180|160 < HCLK <= 168| + +-------------------------------------------------------------------------------------+ + + (#) For STM32F401xx devices, the maximum frequency of the SYSCLK and HCLK is 84 MHz, + PCLK2 84 MHz and PCLK1 42 MHz. Depending on the device voltage range, the maximum + frequency should be adapted accordingly: + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 22 |0 < HCLK <= 20 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |22 < HCLK <= 44 |20 < HCLK <= 40 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|60 < HCLK <= 84 |48 < HCLK <= 72 |44 < HCLK <= 66 |40 < HCLK <= 60 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)| NA |72 < HCLK <= 84 |66 < HCLK <= 84 |60 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)| NA | NA | NA |80 < HCLK <= 84 | + +-------------------------------------------------------------------------------------+ + + (#) For STM32F411xE devices, the maximum frequency of the SYSCLK and HCLK is 100 MHz, + PCLK2 100 MHz and PCLK1 50 MHz. Depending on the device voltage range, the maximum + frequency should be adapted accordingly: + +-------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |---------------------------------------------------------------------| + | | voltage range | voltage range | voltage range | voltage range | + | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | + |---------------|----------------|----------------|-----------------|-----------------| + |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 | + |---------------|----------------|----------------|-----------------|-----------------| + |1WS(2CPU cycle)|30 < HCLK <= 64 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 | + |---------------|----------------|----------------|-----------------|-----------------| + |2WS(3CPU cycle)|64 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 | + |---------------|----------------|----------------|-----------------|-----------------| + |3WS(4CPU cycle)|90 < HCLK <= 100|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 | + |---------------|----------------|----------------|-----------------|-----------------| + |4WS(5CPU cycle)| NA |96 < HCLK <= 100|72 < HCLK <= 90 |64 < HCLK <= 80 | + |---------------|----------------|----------------|-----------------|-----------------| + |5WS(6CPU cycle)| NA | NA |90 < HCLK <= 100 |80 < HCLK <= 96 | + |---------------|----------------|----------------|-----------------|-----------------| + |6WS(7CPU cycle)| NA | NA | NA |96 < HCLK <= 100 | + +-------------------------------------------------------------------------------------+ + + -@- On STM32F405xx/407xx and STM32F415xx/417xx devices: + (++) when VOS = '0', the maximum value of fHCLK = 144MHz. + (++) when VOS = '1', the maximum value of fHCLK = 168MHz. + [..] + On STM32F42xxx/43xxx devices: + (++) when VOS[1:0] = '0x01', the maximum value of fHCLK is 120MHz. + (++) when VOS[1:0] = '0x10', the maximum value of fHCLK is 144MHz. + (++) when VOS[1:0] = '0x11', the maximum value of f is 168MHz + [..] + On STM32F401x devices: + (++) when VOS[1:0] = '0x01', the maximum value of fHCLK is 64MHz. + (++) when VOS[1:0] = '0x10', the maximum value of fHCLK is 84MHz. + On STM32F411xE devices: + (++) when VOS[1:0] = '0x01' the maximum value of fHCLK is 64MHz. + (++) when VOS[1:0] = '0x10' the maximum value of fHCLK is 84MHz. + (++) when VOS[1:0] = '0x11' the maximum value of fHCLK is 100MHz. + + You can use PWR_MainRegulatorModeConfig() function to control VOS bits. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the system clock (SYSCLK). + * @note The HSI is used (enabled by hardware) as system clock source after + * startup from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after startup delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use RCC_GetSYSCLKSource() function to know which clock is + * currently used as system clock source. + * @param RCC_SYSCLKSource: specifies the clock source used as system clock. + * This parameter can be one of the following values: + * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source + * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source + * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source + * @retval None + */ +void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource)); + + tmpreg = RCC->CFGR; + + /* Clear SW[1:0] bits */ + tmpreg &= ~RCC_CFGR_SW; + + /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ + tmpreg |= RCC_SYSCLKSource; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the clock source used as system clock. + * @param None + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * - 0x00: HSI used as system clock + * - 0x04: HSE used as system clock + * - 0x08: PLL used as system clock + */ +uint8_t RCC_GetSYSCLKSource(void) +{ + return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS)); +} + +/** + * @brief Configures the AHB clock (HCLK). + * @note Depending on the device voltage range, the software has to set correctly + * these bits to ensure that HCLK not exceed the maximum allowed frequency + * (for more details refer to section above + * "CPU, AHB and APB busses clocks configuration functions") + * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from + * the system clock (SYSCLK). + * This parameter can be one of the following values: + * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK + * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2 + * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4 + * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8 + * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16 + * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64 + * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128 + * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256 + * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512 + * @retval None + */ +void RCC_HCLKConfig(uint32_t RCC_SYSCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_HCLK(RCC_SYSCLK)); + + tmpreg = RCC->CFGR; + + /* Clear HPRE[3:0] bits */ + tmpreg &= ~RCC_CFGR_HPRE; + + /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ + tmpreg |= RCC_SYSCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + + +/** + * @brief Configures the Low Speed APB clock (PCLK1). + * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB1 clock = HCLK + * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK1Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE1[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE1; + + /* Set PPRE1[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Configures the High Speed APB clock (PCLK2). + * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from + * the AHB clock (HCLK). + * This parameter can be one of the following values: + * @arg RCC_HCLK_Div1: APB2 clock = HCLK + * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2 + * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4 + * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8 + * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16 + * @retval None + */ +void RCC_PCLK2Config(uint32_t RCC_HCLK) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PCLK(RCC_HCLK)); + + tmpreg = RCC->CFGR; + + /* Clear PPRE2[2:0] bits */ + tmpreg &= ~RCC_CFGR_PPRE2; + + /* Set PPRE2[2:0] bits according to RCC_HCLK value */ + tmpreg |= RCC_HCLK << 3; + + /* Store the new value */ + RCC->CFGR = tmpreg; +} + +/** + * @brief Returns the frequencies of different on chip clocks; SYSCLK, HCLK, + * PCLK1 and PCLK2. + * + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) + * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold + * the clocks frequencies. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function + * must be called to update the structure's field. Otherwise, any + * configuration based on this function will be incorrect. + * + * @retval None + */ +void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) +{ + uint32_t tmp = 0, presc = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + RCC_Clocks->SYSCLK_Frequency = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLP + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + RCC_Clocks->SYSCLK_Frequency = pllvco/pllp; + break; + default: + RCC_Clocks->SYSCLK_Frequency = HSI_VALUE; + break; + } + /* Compute HCLK, PCLK1 and PCLK2 clocks frequencies ------------------------*/ + + /* Get HCLK prescaler */ + tmp = RCC->CFGR & RCC_CFGR_HPRE; + tmp = tmp >> 4; + presc = APBAHBPrescTable[tmp]; + /* HCLK clock frequency */ + RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc; + + /* Get PCLK1 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE1; + tmp = tmp >> 10; + presc = APBAHBPrescTable[tmp]; + /* PCLK1 clock frequency */ + RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc; + + /* Get PCLK2 prescaler */ + tmp = RCC->CFGR & RCC_CFGR_PPRE2; + tmp = tmp >> 13; + presc = APBAHBPrescTable[tmp]; + /* PCLK2 clock frequency */ + RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc; +} + +/** + * @} + */ + +/** @defgroup RCC_Group3 Peripheral clocks configuration functions + * @brief Peripheral clocks configuration functions + * +@verbatim + =============================================================================== + ##### Peripheral clocks configuration functions ##### + =============================================================================== + [..] This section provide functions allowing to configure the Peripheral clocks. + + (#) The RTC clock which is derived from the LSI, LSE or HSE clock divided + by 2 to 31. + + (#) After restart from Reset or wakeup from STANDBY, all peripherals are off + except internal SRAM, Flash and JTAG. Before to start using a peripheral + you have to enable its interface clock. You can do this using + RCC_AHBPeriphClockCmd(), RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions. + + (#) To reset the peripherals configuration (to the default state after device reset) + you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and + RCC_APB1PeriphResetCmd() functions. + + (#) To further reduce power consumption in SLEEP mode the peripheral clocks + can be disabled prior to executing the WFI or WFE instructions. + You can do this using RCC_AHBPeriphClockLPModeCmd(), + RCC_APB2PeriphClockLPModeCmd() and RCC_APB1PeriphClockLPModeCmd() functions. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using PWR_BackupAccessCmd(ENABLE) function before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it can't be changed unless the + * Backup domain is reset using RCC_BackupResetCmd() function, or by + * a Power On Reset (POR). + * + * @param RCC_RTCCLKSource: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock + * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock + * @arg RCC_RTCCLKSource_HSE_Divx: HSE clock divided by x selected + * as RTC clock, where x:[2,31] + * + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the HSE clock is used as RTC clock source, the RTC + * cannot be used in STOP and STANDBY modes. + * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as + * RTC clock source). + * + * @retval None + */ +void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource)); + + if ((RCC_RTCCLKSource & 0x00000300) == 0x00000300) + { /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */ + tmpreg = RCC->CFGR; + + /* Clear RTCPRE[4:0] bits */ + tmpreg &= ~RCC_CFGR_RTCPRE; + + /* Configure HSE division factor for RTC clock */ + tmpreg |= (RCC_RTCCLKSource & 0xFFFFCFF); + + /* Store the new value */ + RCC->CFGR = tmpreg; + } + + /* Select the RTC clock source */ + RCC->BDCR |= (RCC_RTCCLKSource & 0x00000FFF); +} + +/** + * @brief Enables or disables the RTC clock. + * @note This function must be used only after the RTC clock source was selected + * using the RCC_RTCCLKConfig function. + * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_RTCCLKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState; +} + +/** + * @brief Forces or releases the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_CSR register. + * @note The BKPSRAM is not affected by this reset. + * @param NewState: new state of the Backup domain reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_BackupResetCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState; +} + +/** + * @brief Configures the I2S clock source (I2SCLK). + * @note This function must be called before enabling the I2S APB clock. + * @param RCC_I2SCLKSource: specifies the I2S clock source. + * This parameter can be one of the following values: + * @arg RCC_I2S2CLKSource_PLLI2S: PLLI2S clock used as I2S clock source + * @arg RCC_I2S2CLKSource_Ext: External clock mapped on the I2S_CKIN pin + * used as I2S clock source + * @retval None + */ +void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource) +{ + /* Check the parameters */ + assert_param(IS_RCC_I2SCLK_SOURCE(RCC_I2SCLKSource)); + + *(__IO uint32_t *) CFGR_I2SSRC_BB = RCC_I2SCLKSource; +} + +/** + * @brief Configures the SAI clock Divider coming from PLLI2S. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note This function must be called before enabling the PLLI2S. + * + * @param RCC_PLLI2SDivQ: specifies the PLLI2S division factor for SAI1 clock . + * This parameter must be a number between 1 and 32. + * SAI1 clock frequency = f(PLLI2S_Q) / RCC_PLLI2SDivQ + * + * @retval None + */ +void RCC_SAIPLLI2SClkDivConfig(uint32_t RCC_PLLI2SDivQ) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(RCC_PLLI2SDivQ)); + + tmpreg = RCC->DCKCFGR; + + /* Clear PLLI2SDIVQ[4:0] bits */ + tmpreg &= ~(RCC_DCKCFGR_PLLI2SDIVQ); + + /* Set PLLI2SDIVQ values */ + tmpreg |= (RCC_PLLI2SDivQ - 1); + + /* Store the new value */ + RCC->DCKCFGR = tmpreg; +} + +/** + * @brief Configures the SAI clock Divider coming from PLLSAI. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note This function must be called before enabling the PLLSAI. + * + * @param RCC_PLLSAIDivQ: specifies the PLLSAI division factor for SAI1 clock . + * This parameter must be a number between 1 and 32. + * SAI1 clock frequency = f(PLLSAI_Q) / RCC_PLLSAIDivQ + * + * @retval None + */ +void RCC_SAIPLLSAIClkDivConfig(uint32_t RCC_PLLSAIDivQ) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(RCC_PLLSAIDivQ)); + + tmpreg = RCC->DCKCFGR; + + /* Clear PLLI2SDIVQ[4:0] and PLLSAIDIVQ[4:0] bits */ + tmpreg &= ~(RCC_DCKCFGR_PLLSAIDIVQ); + + /* Set PLLSAIDIVQ values */ + tmpreg |= ((RCC_PLLSAIDivQ - 1) << 8); + + /* Store the new value */ + RCC->DCKCFGR = tmpreg; +} + +/** + * @brief Configures SAI1BlockA clock source selection. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note This function must be called before enabling PLLSAI, PLLI2S and + * the SAI clock. + * @param RCC_SAIBlockACLKSource: specifies the SAI Block A clock source. + * This parameter can be one of the following values: + * @arg RCC_SAIACLKSource_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used + * as SAI1 Block A clock + * @arg RCC_SAIACLKSource_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used + * as SAI1 Block A clock + * @arg RCC_SAIACLKSource_Ext: External clock mapped on the I2S_CKIN pin + * used as SAI1 Block A clock + * @retval None + */ +void RCC_SAIBlockACLKConfig(uint32_t RCC_SAIBlockACLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SAIACLK_SOURCE(RCC_SAIBlockACLKSource)); + + tmpreg = RCC->DCKCFGR; + + /* Clear RCC_DCKCFGR_SAI1ASRC[1:0] bits */ + tmpreg &= ~RCC_DCKCFGR_SAI1ASRC; + + /* Set SAI Block A source selection value */ + tmpreg |= RCC_SAIBlockACLKSource; + + /* Store the new value */ + RCC->DCKCFGR = tmpreg; +} + +/** + * @brief Configures SAI1BlockB clock source selection. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note This function must be called before enabling PLLSAI, PLLI2S and + * the SAI clock. + * @param RCC_SAIBlockBCLKSource: specifies the SAI Block B clock source. + * This parameter can be one of the following values: + * @arg RCC_SAIBCLKSource_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used + * as SAI1 Block B clock + * @arg RCC_SAIBCLKSource_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used + * as SAI1 Block B clock + * @arg RCC_SAIBCLKSource_Ext: External clock mapped on the I2S_CKIN pin + * used as SAI1 Block B clock + * @retval None + */ +void RCC_SAIBlockBCLKConfig(uint32_t RCC_SAIBlockBCLKSource) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_SAIBCLK_SOURCE(RCC_SAIBlockBCLKSource)); + + tmpreg = RCC->DCKCFGR; + + /* Clear RCC_DCKCFGR_SAI1BSRC[1:0] bits */ + tmpreg &= ~RCC_DCKCFGR_SAI1BSRC; + + /* Set SAI Block B source selection value */ + tmpreg |= RCC_SAIBlockBCLKSource; + + /* Store the new value */ + RCC->DCKCFGR = tmpreg; +} + + +/** + * @brief Configures the LTDC clock Divider coming from PLLSAI. + * + * @note The LTDC peripheral is only available with STM32F429xx/439xx Devices. + * + * @note This function must be called before enabling the PLLSAI. + * + * @param RCC_PLLSAIDivR: specifies the PLLSAI division factor for LTDC clock . + * This parameter must be a number between 2 and 16. + * LTDC clock frequency = f(PLLSAI_R) / RCC_PLLSAIDivR + * + * @retval None + */ +void RCC_LTDCCLKDivConfig(uint32_t RCC_PLLSAIDivR) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PLLSAI_DIVR_VALUE(RCC_PLLSAIDivR)); + + tmpreg = RCC->DCKCFGR; + + /* Clear PLLSAIDIVR[2:0] bits */ + tmpreg &= ~RCC_DCKCFGR_PLLSAIDIVR; + + /* Set PLLSAIDIVR values */ + tmpreg |= RCC_PLLSAIDivR; + + /* Store the new value */ + RCC->DCKCFGR = tmpreg; +} + +/** + * @brief Configures the Timers clocks prescalers selection. + * + * @note This function can be used only for STM32F42xxx/43xxx and STM32F401xx/411xE devices. + * + * @param RCC_TIMCLKPrescaler : specifies the Timers clocks prescalers selection + * This parameter can be one of the following values: + * @arg RCC_TIMPrescDesactivated: The Timers kernels clocks prescaler is + * equal to HPRE if PPREx is corresponding to division by 1 or 2, + * else it is equal to [(HPRE * PPREx) / 2] if PPREx is corresponding to + * division by 4 or more. + * + * @arg RCC_TIMPrescActivated: The Timers kernels clocks prescaler is + * equal to HPRE if PPREx is corresponding to division by 1, 2 or 4, + * else it is equal to [(HPRE * PPREx) / 4] if PPREx is corresponding + * to division by 8 or more. + * @retval None + */ +void RCC_TIMCLKPresConfig(uint32_t RCC_TIMCLKPrescaler) +{ + /* Check the parameters */ + assert_param(IS_RCC_TIMCLK_PRESCALER(RCC_TIMCLKPrescaler)); + + *(__IO uint32_t *) DCKCFGR_TIMPRE_BB = RCC_TIMCLKPrescaler; + +} + +/** + * @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_GPIOJ: GPIOJ clock (STM32F42xxx/43xxx devices) + * @arg RCC_AHB1Periph_GPIOK: GPIOK clock (STM32F42xxx/43xxx devices) + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock + * @arg RCC_AHB1Periph_CCMDATARAMEN CCM data RAM interface clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_DMA2D: DMA2D clock (STM32F429xx/439xx devices) + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock + * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock + * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph)); + + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB1ENR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1ENR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Enables or disables the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2ENR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2ENR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Enables or disables the AHB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. + * This parameter must be: RCC_AHB3Periph_FSMC + * or RCC_AHB3Periph_FMC (STM32F42xxx/43xxx devices) + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3ENR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3ENR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_UART7: UART7 clock + * @arg RCC_APB1Periph_UART8: UART8 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB1ENR |= RCC_APB1Periph; + } + else + { + RCC->APB1ENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SPI4: SPI4 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_SPI5: SPI5 clock + * @arg RCC_APB2Periph_SPI6: SPI6 clock + * @arg RCC_APB2Periph_SAI1: SAI1 clock (STM32F42xxx/43xxx devices) + * @arg RCC_APB2Periph_LTDC: LTDC clock (STM32F429xx/439xx devices) + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->APB2ENR |= RCC_APB2Periph; + } + else + { + RCC->APB2ENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Forces or releases AHB1 peripheral reset. + * @param RCC_AHB1Periph: specifies the AHB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_GPIOJ: GPIOJ clock (STM32F42xxx/43xxx devices) + * @arg RCC_AHB1Periph_GPIOK: GPIOK clock (STM32F42xxx/43xxxdevices) + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_DMA2D: DMA2D clock (STM32F429xx/439xx devices) + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_RESET_PERIPH(RCC_AHB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB1RSTR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1RSTR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Forces or releases AHB2 peripheral reset. + * @param RCC_AHB2Periph: specifies the AHB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB2RSTR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2RSTR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Forces or releases AHB3 peripheral reset. + * @param RCC_AHB3Periph: specifies the AHB3 peripheral to reset. + * This parameter must be: RCC_AHB3Periph_FSMC + * or RCC_AHB3Periph_FMC (STM32F42xxx/43xxx devices) + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RCC->AHB3RSTR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3RSTR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Forces or releases Low Speed APB (APB1) peripheral reset. + * @param RCC_APB1Periph: specifies the APB1 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_UART7: UART7 clock + * @arg RCC_APB1Periph_UART8: UART8 clock + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1RSTR |= RCC_APB1Periph; + } + else + { + RCC->APB1RSTR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Forces or releases High Speed APB (APB2) peripheral reset. + * @param RCC_APB2Periph: specifies the APB2 peripheral to reset. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SPI4: SPI4 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_SPI5: SPI5 clock + * @arg RCC_APB2Periph_SPI6: SPI6 clock + * @arg RCC_APB2Periph_SAI1: SAI1 clock (STM32F42xxx/43xxx devices) + * @arg RCC_APB2Periph_LTDC: LTDC clock (STM32F429xx/439xx devices) + * @param NewState: new state of the specified peripheral reset. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_RESET_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2RSTR |= RCC_APB2Periph; + } + else + { + RCC->APB2RSTR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Enables or disables the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB1Periph_GPIOA: GPIOA clock + * @arg RCC_AHB1Periph_GPIOB: GPIOB clock + * @arg RCC_AHB1Periph_GPIOC: GPIOC clock + * @arg RCC_AHB1Periph_GPIOD: GPIOD clock + * @arg RCC_AHB1Periph_GPIOE: GPIOE clock + * @arg RCC_AHB1Periph_GPIOF: GPIOF clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOG: GPIOG clock + * @arg RCC_AHB1Periph_GPIOI: GPIOI clock + * @arg RCC_AHB1Periph_GPIOJ: GPIOJ clock (STM32F42xxx/43xxx devices) + * @arg RCC_AHB1Periph_GPIOK: GPIOK clock (STM32F42xxx/43xxx devices) + * @arg RCC_AHB1Periph_CRC: CRC clock + * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock + * @arg RCC_AHB1Periph_DMA1: DMA1 clock + * @arg RCC_AHB1Periph_DMA2: DMA2 clock + * @arg RCC_AHB1Periph_DMA2D: DMA2D clock (STM32F429xx/439xx devices) + * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock + * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock + * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock + * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock + * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock + * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB1_LPMODE_PERIPH(RCC_AHB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB1LPENR |= RCC_AHB1Periph; + } + else + { + RCC->AHB1LPENR &= ~RCC_AHB1Periph; + } +} + +/** + * @brief Enables or disables the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_AHB2Periph_DCMI: DCMI clock + * @arg RCC_AHB2Periph_CRYP: CRYP clock + * @arg RCC_AHB2Periph_HASH: HASH clock + * @arg RCC_AHB2Periph_RNG: RNG clock + * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB2LPENR |= RCC_AHB2Periph; + } + else + { + RCC->AHB2LPENR &= ~RCC_AHB2Periph; + } +} + +/** + * @brief Enables or disables the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock. + * This parameter must be: RCC_AHB3Periph_FSMC + * or RCC_AHB3Periph_FMC (STM32F429x/439x devices) + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->AHB3LPENR |= RCC_AHB3Periph; + } + else + { + RCC->AHB3LPENR &= ~RCC_AHB3Periph; + } +} + +/** + * @brief Enables or disables the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB1Periph_TIM2: TIM2 clock + * @arg RCC_APB1Periph_TIM3: TIM3 clock + * @arg RCC_APB1Periph_TIM4: TIM4 clock + * @arg RCC_APB1Periph_TIM5: TIM5 clock + * @arg RCC_APB1Periph_TIM6: TIM6 clock + * @arg RCC_APB1Periph_TIM7: TIM7 clock + * @arg RCC_APB1Periph_TIM12: TIM12 clock + * @arg RCC_APB1Periph_TIM13: TIM13 clock + * @arg RCC_APB1Periph_TIM14: TIM14 clock + * @arg RCC_APB1Periph_WWDG: WWDG clock + * @arg RCC_APB1Periph_SPI2: SPI2 clock + * @arg RCC_APB1Periph_SPI3: SPI3 clock + * @arg RCC_APB1Periph_USART2: USART2 clock + * @arg RCC_APB1Periph_USART3: USART3 clock + * @arg RCC_APB1Periph_UART4: UART4 clock + * @arg RCC_APB1Periph_UART5: UART5 clock + * @arg RCC_APB1Periph_I2C1: I2C1 clock + * @arg RCC_APB1Periph_I2C2: I2C2 clock + * @arg RCC_APB1Periph_I2C3: I2C3 clock + * @arg RCC_APB1Periph_CAN1: CAN1 clock + * @arg RCC_APB1Periph_CAN2: CAN2 clock + * @arg RCC_APB1Periph_PWR: PWR clock + * @arg RCC_APB1Periph_DAC: DAC clock + * @arg RCC_APB1Periph_UART7: UART7 clock + * @arg RCC_APB1Periph_UART8: UART8 clock + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB1LPENR |= RCC_APB1Periph; + } + else + { + RCC->APB1LPENR &= ~RCC_APB1Periph; + } +} + +/** + * @brief Enables or disables the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. + * This parameter can be any combination of the following values: + * @arg RCC_APB2Periph_TIM1: TIM1 clock + * @arg RCC_APB2Periph_TIM8: TIM8 clock + * @arg RCC_APB2Periph_USART1: USART1 clock + * @arg RCC_APB2Periph_USART6: USART6 clock + * @arg RCC_APB2Periph_ADC1: ADC1 clock + * @arg RCC_APB2Periph_ADC2: ADC2 clock + * @arg RCC_APB2Periph_ADC3: ADC3 clock + * @arg RCC_APB2Periph_SDIO: SDIO clock + * @arg RCC_APB2Periph_SPI1: SPI1 clock + * @arg RCC_APB2Periph_SPI4: SPI4 clock + * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock + * @arg RCC_APB2Periph_TIM9: TIM9 clock + * @arg RCC_APB2Periph_TIM10: TIM10 clock + * @arg RCC_APB2Periph_TIM11: TIM11 clock + * @arg RCC_APB2Periph_SPI5: SPI5 clock + * @arg RCC_APB2Periph_SPI6: SPI6 clock + * @arg RCC_APB2Periph_SAI1: SAI1 clock (STM32F42xxx/43xxx devices) + * @arg RCC_APB2Periph_LTDC: LTDC clock (STM32F429xx/439xx devices) + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + RCC->APB2LPENR |= RCC_APB2Periph; + } + else + { + RCC->APB2LPENR &= ~RCC_APB2Periph; + } +} + +/** + * @brief Configures the External Low Speed oscillator mode (LSE mode). + * @note This mode is only available for STM32F411xx devices. + * @param Mode: specifies the LSE mode. + * This parameter can be one of the following values: + * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode. + * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode. + * @retval None + */ +void RCC_LSEModeConfig(uint8_t Mode) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE_MODE(Mode)); + + if(Mode == RCC_LSE_HIGHDRIVE_MODE) + { + SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); + } + else + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); + } +} + +/** + * @} + */ + +/** @defgroup RCC_Group4 Interrupts and flags management functions + * @brief Interrupts and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified RCC interrupts. + * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @arg RCC_IT_PLLSAIRDY: PLLSAI ready interrupt (only for STM32F42xxx/43xxx devices) + * @param NewState: new state of the specified RCC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RCC_IT(RCC_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Perform Byte access to RCC_CIR[14:8] bits to enable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT; + } + else + { + /* Perform Byte access to RCC_CIR[14:8] bits to disable the selected interrupts */ + *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT; + } +} + +/** + * @brief Checks whether the specified RCC flag is set or not. + * @param RCC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready + * @arg RCC_FLAG_PLLRDY: main PLL clock ready + * @arg RCC_FLAG_PLLI2SRDY: PLLI2S clock ready + * @arg RCC_FLAG_PLLSAIRDY: PLLSAI clock ready (only for STM32F42xxx/43xxx devices) + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready + * @arg RCC_FLAG_BORRST: POR/PDR or BOR reset + * @arg RCC_FLAG_PINRST: Pin reset + * @arg RCC_FLAG_PORRST: POR/PDR reset + * @arg RCC_FLAG_SFTRST: Software reset + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset + * @arg RCC_FLAG_LPWRRST: Low Power reset + * @retval The new state of RCC_FLAG (SET or RESET). + */ +FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) +{ + uint32_t tmp = 0; + uint32_t statusreg = 0; + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_FLAG(RCC_FLAG)); + + /* Get the RCC register index */ + tmp = RCC_FLAG >> 5; + if (tmp == 1) /* The flag to check is in CR register */ + { + statusreg = RCC->CR; + } + else if (tmp == 2) /* The flag to check is in BDCR register */ + { + statusreg = RCC->BDCR; + } + else /* The flag to check is in CSR register */ + { + statusreg = RCC->CSR; + } + + /* Get the flag position */ + tmp = RCC_FLAG & FLAG_MASK; + if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the flag status */ + return bitstatus; +} + +/** + * @brief Clears the RCC reset flags. + * The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST + * @param None + * @retval None + */ +void RCC_ClearFlag(void) +{ + /* Set RMVF bit to clear the reset flags */ + RCC->CSR |= RCC_CSR_RMVF; +} + +/** + * @brief Checks whether the specified RCC interrupt has occurred or not. + * @param RCC_IT: specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @arg RCC_IT_PLLSAIRDY: PLLSAI clock ready interrupt (only for STM32F42xxx/43xxx devices) + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval The new state of RCC_IT (SET or RESET). + */ +ITStatus RCC_GetITStatus(uint8_t RCC_IT) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_GET_IT(RCC_IT)); + + /* Check the status of the specified RCC interrupt */ + if ((RCC->CIR & RCC_IT) != (uint32_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + /* Return the RCC_IT status */ + return bitstatus; +} + +/** + * @brief Clears the RCC's interrupt pending bits. + * @param RCC_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt + * @arg RCC_IT_LSERDY: LSE ready interrupt + * @arg RCC_IT_HSIRDY: HSI ready interrupt + * @arg RCC_IT_HSERDY: HSE ready interrupt + * @arg RCC_IT_PLLRDY: main PLL ready interrupt + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt + * @arg RCC_IT_PLLSAIRDY: PLLSAI ready interrupt (only for STM32F42xxx/43xxx devices) + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval None + */ +void RCC_ClearITPendingBit(uint8_t RCC_IT) +{ + /* Check the parameters */ + assert_param(IS_RCC_CLEAR_IT(RCC_IT)); + + /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt + pending bits */ + *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/DRIVER/src/stm32f4xx_syscfg.c b/DRIVER/src/stm32f4xx_syscfg.c new file mode 100644 index 0000000..29f472d --- /dev/null +++ b/DRIVER/src/stm32f4xx_syscfg.c @@ -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 + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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****/ diff --git a/DRIVER/src/stm32f4xx_tim.c b/DRIVER/src/stm32f4xx_tim.c new file mode 100644 index 0000000..79bd265 --- /dev/null +++ b/DRIVER/src/stm32f4xx_tim.c @@ -0,0 +1,3365 @@ +/** + ****************************************************************************** + * @file stm32f4xx_tim.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 TIM peripheral: + * + TimeBase management + * + Output Compare management + * + Input Capture management + * + Advanced-control timers (TIM1 and TIM8) specific features + * + Interrupts, DMA and flags management + * + Clocks management + * + Synchronization management + * + Specific interface management + * + Specific remapping management + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + This driver provides functions to configure and program the TIM + of all STM32F4xx devices. + These functions are split in 9 groups: + + (#) TIM TimeBase management: this group includes all needed functions + to configure the TM Timebase unit: + (++) Set/Get Prescaler + (++) Set/Get Autoreload + (++) Counter modes configuration + (++) Set Clock division + (++) Select the One Pulse mode + (++) Update Request Configuration + (++) Update Disable Configuration + (++) Auto-Preload Configuration + (++) Enable/Disable the counter + + (#) TIM Output Compare management: this group includes all needed + functions to configure the Capture/Compare unit used in Output + compare mode: + (++) Configure each channel, independently, in Output Compare mode + (++) Select the output compare modes + (++) Select the Polarities of each channel + (++) Set/Get the Capture/Compare register values + (++) Select the Output Compare Fast mode + (++) Select the Output Compare Forced mode + (++) Output Compare-Preload Configuration + (++) Clear Output Compare Reference + (++) Select the OCREF Clear signal + (++) Enable/Disable the Capture/Compare Channels + + (#) TIM Input Capture management: this group includes all needed + functions to configure the Capture/Compare unit used in + Input Capture mode: + (++) Configure each channel in input capture mode + (++) Configure Channel1/2 in PWM Input mode + (++) Set the Input Capture Prescaler + (++) Get the Capture/Compare values + + (#) Advanced-control timers (TIM1 and TIM8) specific features + (++) Configures the Break input, dead time, Lock level, the OSSI, + the OSSR State and the AOE(automatic output enable) + (++) Enable/Disable the TIM peripheral Main Outputs + (++) Select the Commutation event + (++) Set/Reset the Capture Compare Preload Control bit + + (#) TIM interrupts, DMA and flags management + (++) Enable/Disable interrupt sources + (++) Get flags status + (++) Clear flags/ Pending bits + (++) Enable/Disable DMA requests + (++) Configure DMA burst mode + (++) Select CaptureCompare DMA request + + (#) TIM clocks management: this group includes all needed functions + to configure the clock controller unit: + (++) Select internal/External clock + (++) Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx + + (#) TIM synchronization management: this group includes all needed + functions to configure the Synchronization unit: + (++) Select Input Trigger + (++) Select Output Trigger + (++) Select Master Slave Mode + (++) ETR Configuration when used as external trigger + + (#) TIM specific interface management, this group includes all + needed functions to use the specific TIM interface: + (++) Encoder Interface Configuration + (++) Select Hall Sensor + + (#) TIM specific remapping management includes the Remapping + configuration of specific timers + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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_tim.h" +#include "stm32f4xx_rcc.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @defgroup TIM + * @brief TIM driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* ---------------------- TIM registers bit mask ------------------------ */ +#define SMCR_ETR_MASK ((uint16_t)0x00FF) +#define CCMR_OFFSET ((uint16_t)0x0018) +#define CCER_CCE_SET ((uint16_t)0x0001) +#define CCER_CCNE_SET ((uint16_t)0x0004) +#define CCMR_OC13M_MASK ((uint16_t)0xFF8F) +#define CCMR_OC24M_MASK ((uint16_t)0x8FFF) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter); + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup TIM_Private_Functions + * @{ + */ + +/** @defgroup TIM_Group1 TimeBase management functions + * @brief TimeBase management functions + * +@verbatim + =============================================================================== + ##### TimeBase management functions ##### + =============================================================================== + + + ##### TIM Driver: how to use it in Timing(Time base) Mode ##### + =============================================================================== + [..] + To use the Timer in Timing(Time base) mode, the following steps are mandatory: + + (#) Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function + + (#) Fill the TIM_TimeBaseInitStruct with the desired parameters. + + (#) Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure the Time Base unit + with the corresponding configuration + + (#) Enable the NVIC if you need to generate the update interrupt. + + (#) Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update) + + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + -@- All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval None + + */ +void TIM_DeInit(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx == TIM1) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE); + } + else if (TIMx == TIM2) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE); + } + else if (TIMx == TIM3) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE); + } + else if (TIMx == TIM4) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE); + } + else if (TIMx == TIM5) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE); + } + else if (TIMx == TIM6) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE); + } + else if (TIMx == TIM7) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE); + } + else if (TIMx == TIM8) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE); + } + else if (TIMx == TIM9) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE); + } + else if (TIMx == TIM10) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE); + } + else if (TIMx == TIM11) + { + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE); + } + else if (TIMx == TIM12) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE); + } + else if (TIMx == TIM13) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE); + } + else + { + if (TIMx == TIM14) + { + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE); + RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE); + } + } +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure + * that contains the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); + assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); + + tmpcr1 = TIMx->CR1; + + if((TIMx == TIM1) || (TIMx == TIM8)|| + (TIMx == TIM2) || (TIMx == TIM3)|| + (TIMx == TIM4) || (TIMx == TIM5)) + { + /* Select the Counter Mode */ + tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS)); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode; + } + + if((TIMx != TIM6) && (TIMx != TIM7)) + { + /* Set the clock division */ + tmpcr1 &= (uint16_t)(~TIM_CR1_CKD); + tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ; + + /* Set the Prescaler value */ + TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler; + + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter(only for TIM1 and TIM8) value immediatly */ + TIMx->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each TIM_TimeBaseInitStruct member with its default value. + * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) +{ + /* Set the default configuration */ + TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF; + TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000; + TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000; +} + +/** + * @brief Configures the TIMx Prescaler. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Prescaler: specifies the Prescaler Register value + * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode + * This parameter can be one of the following values: + * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly. + * @retval None + */ +void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode)); + /* Set the Prescaler value */ + TIMx->PSC = Prescaler; + /* Set or reset the UG Bit */ + TIMx->EGR = TIM_PSCReloadMode; +} + +/** + * @brief Specifies the TIMx Counter Mode to be used. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_CounterMode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up: TIM Up Counting Mode + * @arg TIM_CounterMode_Down: TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None + */ +void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode) +{ + uint16_t tmpcr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode)); + + tmpcr1 = TIMx->CR1; + + /* Reset the CMS and DIR Bits */ + tmpcr1 &= (uint16_t)~(TIM_CR1_DIR | TIM_CR1_CMS); + + /* Set the Counter Mode */ + tmpcr1 |= TIM_CounterMode; + + /* Write to TIMx CR1 register */ + TIMx->CR1 = tmpcr1; +} + +/** + * @brief Sets the TIMx Counter Register value + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Counter: specifies the Counter register new value. + * @retval None + */ +void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Counter Register value */ + TIMx->CNT = Counter; +} + +/** + * @brief Sets the TIMx Autoreload Register value + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param Autoreload: specifies the Autoreload register new value. + * @retval None + */ +void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Set the Autoreload Register value */ + TIMx->ARR = Autoreload; +} + +/** + * @brief Gets the TIMx Counter value. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval Counter Register value + */ +uint32_t TIM_GetCounter(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Counter Register value */ + return TIMx->CNT; +} + +/** + * @brief Gets the TIMx Prescaler value. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @retval Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Get the Prescaler Register value */ + return TIMx->PSC; +} + +/** + * @brief Enables or Disables the TIMx Update event. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param NewState: new state of the TIMx UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the Update Disable Bit */ + TIMx->CR1 |= TIM_CR1_UDIS; + } + else + { + /* Reset the Update Disable Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_UDIS; + } +} + +/** + * @brief Configures the TIMx Update Request Interrupt source. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_UpdateSource: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UpdateSource_Global: Source of update is the counter + * overflow/underflow or the setting of UG bit, or an update + * generation through the slave mode controller. + * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow. + * @retval None + */ +void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource)); + + if (TIM_UpdateSource != TIM_UpdateSource_Global) + { + /* Set the URS Bit */ + TIMx->CR1 |= TIM_CR1_URS; + } + else + { + /* Reset the URS Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_URS; + } +} + +/** + * @brief Enables or disables TIMx peripheral Preload register on ARR. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param NewState: new state of the TIMx peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the ARR Preload Bit */ + TIMx->CR1 |= TIM_CR1_ARPE; + } + else + { + /* Reset the ARR Preload Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_ARPE; + } +} + +/** + * @brief Selects the TIMx's One Pulse Mode. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_OPMode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Single + * @arg TIM_OPMode_Repetitive + * @retval None + */ +void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_OPM_MODE(TIM_OPMode)); + + /* Reset the OPM Bit */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + TIMx->CR1 |= TIM_OPMode; +} + +/** + * @brief Sets the TIMx Clock Division value. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_CKD: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV1: TDTS = Tck_tim + * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim + * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim + * @retval None + */ +void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CKD_DIV(TIM_CKD)); + + /* Reset the CKD Bits */ + TIMx->CR1 &= (uint16_t)(~TIM_CR1_CKD); + + /* Set the CKD value */ + TIMx->CR1 |= TIM_CKD; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->CR1 |= TIM_CR1_CEN; + } + else + { + /* Disable the TIM Counter */ + TIMx->CR1 &= (uint16_t)~TIM_CR1_CEN; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group2 Output Compare management functions + * @brief Output Compare management functions + * +@verbatim + =============================================================================== + ##### Output Compare management functions ##### + =============================================================================== + + + ##### TIM Driver: how to use it in Output Compare Mode ##### + =============================================================================== + [..] + To use the Timer in Output Compare mode, the following steps are mandatory: + + (#) Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) + function + + (#) Configure the TIM pins by configuring the corresponding GPIO pins + + (#) Configure the Time base unit as described in the first part of this driver, + (++) if needed, else the Timer will run with the default configuration: + Autoreload value = 0xFFFF + (++) Prescaler value = 0x0000 + (++) Counter mode = Up counting + (++) Clock Division = TIM_CKD_DIV1 + + (#) Fill the TIM_OCInitStruct with the desired parameters including: + (++) The TIM Output Compare mode: TIM_OCMode + (++) TIM Output State: TIM_OutputState + (++) TIM Pulse value: TIM_Pulse + (++) TIM Output Compare Polarity : TIM_OCPolarity + + (#) Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired + channel with the corresponding configuration + + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + -@- All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + + -@- In case of PWM mode, this function is mandatory: + TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE); + + -@- If the corresponding interrupt or DMA request are needed, the user should: + (+@) Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests). + (+@) Enable the corresponding interrupt (or DMA request) using the function + TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIMx Channel1 according to the specified parameters in + * the TIM_OCInitStruct. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR1_OC1M; + tmpccmrx &= (uint16_t)~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCPolarity; + + /* Set the Output State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputState; + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity; + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NE; + + /* Set the Output N State */ + tmpccer |= TIM_OCInitStruct->TIM_OutputNState; + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS1; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState; + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel2 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR1_OC2M; + tmpccmrx &= (uint16_t)~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4); + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NE; + + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4); + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS2; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel3 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR2_OC3M; + tmpccmrx &= (uint16_t)~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= TIM_OCInitStruct->TIM_OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8); + /* Reset the Output N State */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NE; + + /* Set the Output N State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8); + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= (uint16_t)~TIM_CR2_OIS3; + tmpcr2 &= (uint16_t)~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4); + /* Set the Output N Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Initializes the TIMx Channel4 according to the specified parameters + * in the TIM_OCInitStruct. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode)); + assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= (uint16_t)~TIM_CCMR2_OC4M; + tmpccmrx &= (uint16_t)~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= (uint16_t)~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12); + + /* Set the Output State */ + tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12); + + if((TIMx == TIM1) || (TIMx == TIM8)) + { + assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState)); + /* Reset the Output Compare IDLE State */ + tmpcr2 &=(uint16_t) ~TIM_CR2_OIS4; + /* Set the Output Idle state */ + tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Fills each TIM_OCInitStruct member with its default value. + * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct) +{ + /* Set the default configuration */ + TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing; + TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct->TIM_Pulse = 0x00000000; + TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output + * Compare Mode. If needed, user has to enable this channel using + * TIM_CCxCmd() and TIM_CCxNCmd() functions. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_OCMode: specifies the TIM Output Compare Mode. + * This parameter can be one of the following values: + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Toggle + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @arg TIM_ForcedAction_Active + * @arg TIM_ForcedAction_InActive + * @retval None + */ +void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) +{ + uint32_t tmp = 0; + uint16_t tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_OCM(TIM_OCMode)); + + tmp = (uint32_t) TIMx; + tmp += CCMR_OFFSET; + + tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel; + + /* Disable the Channel: Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t) ~tmp1; + + if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) + { + tmp += (TIM_Channel>>1); + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= CCMR_OC13M_MASK; + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= TIM_OCMode; + } + else + { + tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; + + /* Reset the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp &= CCMR_OC24M_MASK; + + /* Configure the OCxM bits in the CCMRx register */ + *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8); + } +} + +/** + * @brief Sets the TIMx Capture Compare1 Register value + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param Compare1: specifies the Capture Compare1 register new value. + * @retval None + */ +void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Set the Capture Compare1 Register value */ + TIMx->CCR1 = Compare1; +} + +/** + * @brief Sets the TIMx Capture Compare2 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param Compare2: specifies the Capture Compare2 register new value. + * @retval None + */ +void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Set the Capture Compare2 Register value */ + TIMx->CCR2 = Compare2; +} + +/** + * @brief Sets the TIMx Capture Compare3 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare3: specifies the Capture Compare3 register new value. + * @retval None + */ +void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare3 Register value */ + TIMx->CCR3 = Compare3; +} + +/** + * @brief Sets the TIMx Capture Compare4 Register value + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param Compare4: specifies the Capture Compare4 register new value. + * @retval None + */ +void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Set the Capture Compare4 Register value */ + TIMx->CCR4 = Compare4; +} + +/** + * @brief Forces the TIMx output 1 waveform to active or inactive level. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF. + * @retval None + */ +void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1M Bits */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1M; + + /* Configure The Forced output Mode */ + tmpccmr1 |= TIM_ForcedAction; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 2 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF. + * @retval None + */ +void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2M Bits */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2M; + + /* Configure The Forced output Mode */ + tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Forces the TIMx output 3 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF. + * @retval None + */ +void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC1M Bits */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3M; + + /* Configure The Forced output Mode */ + tmpccmr2 |= TIM_ForcedAction; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Forces the TIMx output 4 waveform to active or inactive level. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF + * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF. + * @retval None + */ +void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction)); + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC2M Bits */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4M; + + /* Configure The Forced output Mode */ + tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR1. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1PE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC1PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= TIM_OCPreload; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR2. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2PE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR3. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3PE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC3PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= TIM_OCPreload; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Enables or disables the TIMx peripheral Preload register on CCR4. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPreload: new state of the TIMx peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Enable + * @arg TIM_OCPreload_Disable + * @retval None + */ +void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4PE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4PE); + + /* Enable or Disable the Output Compare Preload feature */ + tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 1 Fast feature. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1FE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1FE; + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= TIM_OCFast; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 2 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2FE Bit */ + tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Configures the TIMx Output Compare 3 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3FE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3FE; + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= TIM_OCFast; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx Output Compare 4 Fast feature. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None + */ +void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast)); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4FE Bit */ + tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4FE); + + /* Enable or Disable the Output Compare Fast Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCFast << 8); + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC1CE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= TIM_OCClear; + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr1 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr1 = TIMx->CCMR1; + + /* Reset the OC2CE Bit */ + tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr1 |= (uint16_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR1 register */ + TIMx->CCMR1 = tmpccmr1; +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC3CE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= TIM_OCClear; + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear) +{ + uint16_t tmpccmr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear)); + + tmpccmr2 = TIMx->CCMR2; + + /* Reset the OC4CE Bit */ + tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4CE; + + /* Enable or Disable the Output Compare Clear Bit */ + tmpccmr2 |= (uint16_t)(TIM_OCClear << 8); + + /* Write to TIMx CCMR2 register */ + TIMx->CCMR2 = tmpccmr2; +} + +/** + * @brief Configures the TIMx channel 1 polarity. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1P Bit */ + tmpccer &= (uint16_t)(~TIM_CCER_CC1P); + tmpccer |= TIM_OCPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 1N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC1N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC1NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC1NP; + tmpccer |= TIM_OCNPolarity; + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 2 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_OCPolarity: specifies the OC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2P Bit */ + tmpccer &= (uint16_t)(~TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_OCPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 2N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC2N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC2NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC2NP; + tmpccer |= (uint16_t)(TIM_OCNPolarity << 4); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 3 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC3 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3P Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC3P; + tmpccer |= (uint16_t)(TIM_OCPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx Channel 3N polarity. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_OCNPolarity: specifies the OC3N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC3NP Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC3NP; + tmpccer |= (uint16_t)(TIM_OCNPolarity << 8); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Configures the TIMx channel 4 polarity. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_OCPolarity: specifies the OC4 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None + */ +void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity) +{ + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity)); + + tmpccer = TIMx->CCER; + + /* Set or Reset the CC4P Bit */ + tmpccer &= (uint16_t)~TIM_CCER_CC4P; + tmpccer |= (uint16_t)(TIM_OCPolarity << 12); + + /* Write to TIMx CCER register */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None + */ +void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCX(TIM_CCx)); + + tmp = CCER_CCE_SET << TIM_Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= (uint16_t)~ tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx: where x can be 1 or 8 to select the TIM peripheral. + * @param TIM_Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable. + * @retval None + */ +void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN) +{ + uint16_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel)); + assert_param(IS_TIM_CCXN(TIM_CCxN)); + + tmp = CCER_CCNE_SET << TIM_Channel; + + /* Reset the CCxNE Bit */ + TIMx->CCER &= (uint16_t) ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel); +} +/** + * @} + */ + +/** @defgroup TIM_Group3 Input Capture management functions + * @brief Input Capture management functions + * +@verbatim + =============================================================================== + ##### Input Capture management functions ##### + =============================================================================== + + ##### TIM Driver: how to use it in Input Capture Mode ##### + =============================================================================== + [..] + To use the Timer in Input Capture mode, the following steps are mandatory: + + (#) Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) + function + + (#) Configure the TIM pins by configuring the corresponding GPIO pins + + (#) Configure the Time base unit as described in the first part of this driver, + if needed, else the Timer will run with the default configuration: + (++) Autoreload value = 0xFFFF + (++) Prescaler value = 0x0000 + (++) Counter mode = Up counting + (++) Clock Division = TIM_CKD_DIV1 + + (#) Fill the TIM_ICInitStruct with the desired parameters including: + (++) TIM Channel: TIM_Channel + (++) TIM Input Capture polarity: TIM_ICPolarity + (++) TIM Input Capture selection: TIM_ICSelection + (++) TIM Input Capture Prescaler: TIM_ICPrescaler + (++) TIM Input CApture filter value: TIM_ICFilter + + (#) Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired channel + with the corresponding configuration and to measure only frequency + or duty cycle of the input signal, or, Call TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) + to configure the desired channels with the corresponding configuration + and to measure the frequency and the duty cycle of the input signal + + (#) Enable the NVIC or the DMA to read the measured frequency. + + (#) Enable the corresponding interrupt (or DMA request) to read the Captured + value, using the function TIM_ITConfig(TIMx, TIM_IT_CCx) + (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx)) + + (#) Call the TIM_Cmd(ENABLE) function to enable the TIM counter. + + (#) Use TIM_GetCapturex(TIMx); to read the captured value. + + -@- All other functions can be used separately to modify, if needed, + a specific feature of the Timer. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM peripheral according to the specified parameters + * in the TIM_ICInitStruct. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter)); + + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI4 Configuration */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, + TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each TIM_ICInitStruct member with its default value. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None + */ +void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->TIM_Channel = TIM_Channel_1; + TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStruct->TIM_ICFilter = 0x00; +} + +/** + * @brief Configures the TIM peripheral according to the specified parameters + * in the TIM_ICInitStruct to measure an external PWM signal. + * @param TIMx: where x can be 1, 2, 3, 4, 5,8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains + * the configuration information for the specified TIM peripheral. + * @retval None + */ +void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Select the Opposite Input Polarity */ + if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising) + { + icoppositepolarity = TIM_ICPolarity_Falling; + } + else + { + icoppositepolarity = TIM_ICPolarity_Rising; + } + /* Select the Opposite Input */ + if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI) + { + icoppositeselection = TIM_ICSelection_IndirectTI; + } + else + { + icoppositeselection = TIM_ICSelection_DirectTI; + } + if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1) + { + /* TI1 Configuration */ + TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI2 Configuration */ + TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } + else + { + /* TI2 Configuration */ + TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection, + TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + /* TI1 Configuration */ + TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter); + /* Set the Input Capture Prescaler value */ + TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler); + } +} + +/** + * @brief Gets the TIMx Input Capture 1 value. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @retval Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + + /* Get the Capture 1 Register value */ + return TIMx->CCR1; +} + +/** + * @brief Gets the TIMx Input Capture 2 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @retval Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Get the Capture 2 Register value */ + return TIMx->CCR2; +} + +/** + * @brief Gets the TIMx Input Capture 3 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 3 Register value */ + return TIMx->CCR3; +} + +/** + * @brief Gets the TIMx Input Capture 4 value. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @retval Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + + /* Get the Capture 4 Register value */ + return TIMx->CCR4; +} + +/** + * @brief Sets the TIMx Input Capture 1 prescaler. + * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC1PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + TIMx->CCMR1 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 2 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC2PSC Bits */ + TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8); +} + +/** + * @brief Sets the TIMx Input Capture 3 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC3PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + TIMx->CCMR2 |= TIM_ICPSC; +} + +/** + * @brief Sets the TIMx Input Capture 4 prescaler. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC)); + + /* Reset the IC4PSC Bits */ + TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8); +} +/** + * @} + */ + +/** @defgroup TIM_Group4 Advanced-control timers (TIM1 and TIM8) specific features + * @brief Advanced-control timers (TIM1 and TIM8) specific features + * +@verbatim + =============================================================================== + ##### Advanced-control timers (TIM1 and TIM8) specific features ##### + =============================================================================== + + ##### TIM Driver: how to use the Break feature ##### + =============================================================================== + [..] + After configuring the Timer channel(s) in the appropriate Output Compare mode: + + (#) Fill the TIM_BDTRInitStruct with the desired parameters for the Timer + Break Polarity, dead time, Lock level, the OSSI/OSSR State and the + AOE(automatic output enable). + + (#) Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer + + (#) Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE) + + (#) Once the break even occurs, the Timer's output signals are put in reset + state or in a known state (according to the configuration made in + TIM_BDTRConfig() function). + +@endverbatim + * @{ + */ + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param TIMx: where x can be 1 or 8 to select the TIM + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None + */ +void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState)); + assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState)); + assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel)); + assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break)); + assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput)); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState | + TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime | + TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity | + TIM_BDTRInitStruct->TIM_AutomaticOutput; +} + +/** + * @brief Fills each TIM_BDTRInitStruct member with its default value. + * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which + * will be initialized. + * @retval None + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable; + TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable; + TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF; + TIM_BDTRInitStruct->TIM_DeadTime = 0x00; + TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable; + TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral. + * @param NewState: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Main Output */ + TIMx->BDTR |= TIM_BDTR_MOE; + } + else + { + /* Disable the TIM Main Output */ + TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE; + } +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the COM Bit */ + TIMx->CR2 |= TIM_CR2_CCUS; + } + else + { + /* Reset the COM Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCUS; + } +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral + * @param NewState: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST4_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + if (NewState != DISABLE) + { + /* Set the CCPC Bit */ + TIMx->CR2 |= TIM_CR2_CCPC; + } + else + { + /* Reset the CCPC Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCPC; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group5 Interrupts DMA and flags management functions + * @brief Interrupts, DMA and flags management functions + * +@verbatim + =============================================================================== + ##### Interrupts, DMA and flags management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral. + * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note For TIM6 and TIM7 only the parameter TIM_IT_Update can be used + * @note For TIM9 and TIM12 only one of the following parameters can be used: TIM_IT_Update, + * TIM_IT_CC1, TIM_IT_CC2 or TIM_IT_Trigger. + * @note For TIM10, TIM11, TIM13 and TIM14 only one of the following parameters can + * be used: TIM_IT_Update or TIM_IT_CC1 + * @note TIM_IT_COM and TIM_IT_Break can be used only with TIM1 and TIM8 + * + * @param NewState: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_IT(TIM_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->DIER |= TIM_IT; + } + else + { + /* Disable the Interrupt sources */ + TIMx->DIER &= (uint16_t)~TIM_IT; + } +} + +/** + * @brief Configures the TIMx event to be generate by software. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_EventSource: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update: Timer update Event source + * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EventSource_COM: Timer COM event source + * @arg TIM_EventSource_Trigger: Timer Trigger Event source + * @arg TIM_EventSource_Break: Timer Break event source + * + * @note TIM6 and TIM7 can only generate an update event. + * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource)); + + /* Set the event sources */ + TIMx->EGR = TIM_EventSource; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag + * + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. + * + * @retval The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + ITStatus bitstatus = RESET; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_FLAG(TIM_FLAG)); + + + if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's pending flags. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_FLAG: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag + * + * @note TIM6 and TIM7 can have only one update flag. + * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Clear the flags */ + TIMx->SR = (uint16_t)~TIM_FLAG; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_IT: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. + * + * @retval The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + ITStatus bitstatus = RESET; + uint16_t itstatus = 0x0, itenable = 0x0; + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_GET_IT(TIM_IT)); + + itstatus = TIMx->SR & TIM_IT; + + itenable = TIMx->DIER & TIM_IT; + if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET)) + { + bitstatus = SET; + } + else + { + bitstatus = RESET; + } + return bitstatus; +} + +/** + * @brief Clears the TIMx's interrupt pending bits. + * @param TIMx: where x can be 1 to 14 to select the TIM peripheral. + * @param TIM_IT: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM1 update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * + * @note TIM6 and TIM7 can generate only an update interrupt. + * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8. + * + * @retval None + */ +void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + /* Clear the IT pending Bit */ + TIMx->SR = (uint16_t)~TIM_IT; +} + +/** + * @brief Configures the TIMx's DMA interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_DMABase: DMA Base address. + * This parameter can be one of the following values: + * @arg TIM_DMABase_CR1 + * @arg TIM_DMABase_CR2 + * @arg TIM_DMABase_SMCR + * @arg TIM_DMABase_DIER + * @arg TIM1_DMABase_SR + * @arg TIM_DMABase_EGR + * @arg TIM_DMABase_CCMR1 + * @arg TIM_DMABase_CCMR2 + * @arg TIM_DMABase_CCER + * @arg TIM_DMABase_CNT + * @arg TIM_DMABase_PSC + * @arg TIM_DMABase_ARR + * @arg TIM_DMABase_RCR + * @arg TIM_DMABase_CCR1 + * @arg TIM_DMABase_CCR2 + * @arg TIM_DMABase_CCR3 + * @arg TIM_DMABase_CCR4 + * @arg TIM_DMABase_BDTR + * @arg TIM_DMABase_DCR + * @param TIM_DMABurstLength: DMA Burst length. This parameter can be one value + * between: TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers. + * @retval None + */ +void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_BASE(TIM_DMABase)); + assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength)); + + /* Set the DMA Base and the DMA Burst Length */ + TIMx->DCR = TIM_DMABase | TIM_DMABurstLength; +} + +/** + * @brief Enables or disables the TIMx's DMA Requests. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * @param TIM_DMASource: specifies the DMA Request sources. + * This parameter can be any combination of the following values: + * @arg TIM_DMA_Update: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_Trigger: TIM Trigger DMA source + * @param NewState: new state of the DMA Request sources. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the DMA sources */ + TIMx->DIER |= TIM_DMASource; + } + else + { + /* Disable the DMA sources */ + TIMx->DIER &= (uint16_t)~TIM_DMASource; + } +} + +/** + * @brief Selects the TIMx peripheral Capture Compare DMA source. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param NewState: new state of the Capture Compare DMA source + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the CCDS Bit */ + TIMx->CR2 |= TIM_CR2_CCDS; + } + else + { + /* Reset the CCDS Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_CCDS; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group6 Clocks management functions + * @brief Clocks management functions + * +@verbatim + =============================================================================== + ##### Clocks management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx internal Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @retval None + */ +void TIM_InternalClockConfig(TIM_TypeDef* TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + + /* Disable slave mode to clock the prescaler directly with the internal clock */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; +} + +/** + * @brief Configures the TIMx Internal Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_InputTriggerSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @retval None + */ +void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Select the Internal Trigger */ + TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource); + + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter: specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, + uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity)); + assert_param(IS_TIM_IC_FILTER(ICFilter)); + + /* Configure the Timer Input Clock Source */ + if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2) + { + TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + else + { + TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter); + } + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the SMS Bits */ + tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; + + /* Select the External clock mode1 */ + tmpsmcr |= TIM_SlaveMode_External1; + + /* Select the Trigger selection : ETRF */ + tmpsmcr &= (uint16_t)~TIM_SMCR_TS; + tmpsmcr |= TIM_TS_ETRF; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + /* Configure the ETR Clock source */ + TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Enable the External clock mode2 */ + TIMx->SMCR |= TIM_SMCR_ECE; +} +/** + * @} + */ + +/** @defgroup TIM_Group7 Synchronization management functions + * @brief Synchronization management functions + * +@verbatim + =============================================================================== + ##### Synchronization management functions ##### + =============================================================================== + + ##### TIM Driver: how to use it in synchronization Mode ##### + =============================================================================== + [..] + + *** Case of two/several Timers *** + ================================== + [..] + (#) Configure the Master Timers using the following functions: + (++) void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); + (++) void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode); + (#) Configure the Slave Timers using the following functions: + (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); + (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + + *** Case of Timers and external trigger(ETR pin) *** + ==================================================== + [..] + (#) Configure the External trigger using this function: + (++) void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, + uint16_t ExtTRGFilter); + (#) Configure the Slave Timers using the following functions: + (++) void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); + (++) void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); + +@endverbatim + * @{ + */ + +/** + * @brief Selects the Input Trigger source + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_InputTriggerSource: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST1_PERIPH(TIMx)); + assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Reset the TS Bits */ + tmpsmcr &= (uint16_t)~TIM_SMCR_TS; + + /* Set the Input Trigger source */ + tmpsmcr |= TIM_InputTriggerSource; + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Selects the TIMx Trigger Output Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral. + * + * @param TIM_TRGOSource: specifies the Trigger Output source. + * This parameter can be one of the following values: + * + * - For all TIMx + * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output(TRGO) + * + * - For all TIMx except TIM6 and TIM7 + * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag + * is to be set, as soon as a capture or compare match occurs(TRGO) + * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output(TRGO) + * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output(TRGO) + * + * @retval None + */ +void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST5_PERIPH(TIMx)); + assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource)); + + /* Reset the MMS Bits */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_MMS; + /* Select the TRGO source */ + TIMx->CR2 |= TIM_TRGOSource; +} + +/** + * @brief Selects the TIMx Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_SlaveMode: specifies the Timer Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal(TRGI) reinitialize + * the counter and triggers an update of the registers + * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high + * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter + * @retval None + */ +void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode)); + + /* Reset the SMS Bits */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS; + + /* Select the Slave Mode */ + TIMx->SMCR |= TIM_SlaveMode; +} + +/** + * @brief Sets or Resets the TIMx Master/Slave Mode. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral. + * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode. + * This parameter can be one of the following values: + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer + * and its slaves (through TRGO) + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None + */ +void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode)); + + /* Reset the MSM Bit */ + TIMx->SMCR &= (uint16_t)~TIM_SMCR_MSM; + + /* Set or Reset the MSM Bit */ + TIMx->SMCR |= TIM_MasterSlaveMode; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, + uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + uint16_t tmpsmcr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST3_PERIPH(TIMx)); + assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler)); + assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity)); + assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter)); + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= SMCR_ETR_MASK; + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +/** + * @} + */ + +/** @defgroup TIM_Group8 Specific interface management functions + * @brief Specific interface management functions + * +@verbatim + =============================================================================== + ##### Specific interface management functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIMx Encoder Interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_EncoderMode: specifies the TIMx Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param TIM_IC1Polarity: specifies the IC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param TIM_IC2Polarity: specifies the IC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None + */ +void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode, + uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity) +{ + uint16_t tmpsmcr = 0; + uint16_t tmpccmr1 = 0; + uint16_t tmpccer = 0; + + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity)); + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = TIMx->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Set the encoder Mode */ + tmpsmcr &= (uint16_t)~TIM_SMCR_SMS; + tmpsmcr |= TIM_EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S); + tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0; + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P); + tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4)); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Enables or disables the TIMx's Hall sensor interface. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param NewState: new state of the TIMx Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST2_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Set the TI1S Bit */ + TIMx->CR2 |= TIM_CR2_TI1S; + } + else + { + /* Reset the TI1S Bit */ + TIMx->CR2 &= (uint16_t)~TIM_CR2_TI1S; + } +} +/** + * @} + */ + +/** @defgroup TIM_Group9 Specific remapping management function + * @brief Specific remapping management function + * +@verbatim + =============================================================================== + ##### Specific remapping management function ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configures the TIM2, TIM5 and TIM11 Remapping input capabilities. + * @param TIMx: where x can be 2, 5 or 11 to select the TIM peripheral. + * @param TIM_Remap: specifies the TIM input remapping source. + * This parameter can be one of the following values: + * @arg TIM2_TIM8_TRGO: TIM2 ITR1 input is connected to TIM8 Trigger output(default) + * @arg TIM2_ETH_PTP: TIM2 ITR1 input is connected to ETH PTP trogger output. + * @arg TIM2_USBFS_SOF: TIM2 ITR1 input is connected to USB FS SOF. + * @arg TIM2_USBHS_SOF: TIM2 ITR1 input is connected to USB HS SOF. + * @arg TIM5_GPIO: TIM5 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM5_LSI: TIM5 CH4 input is connected to LSI clock. + * @arg TIM5_LSE: TIM5 CH4 input is connected to LSE clock. + * @arg TIM5_RTC: TIM5 CH4 input is connected to RTC Output event. + * @arg TIM11_GPIO: TIM11 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM11_HSE: TIM11 CH4 input is connected to HSE_RTC clock + * (HSE divided by a programmable prescaler) + * @retval None + */ +void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap) +{ + /* Check the parameters */ + assert_param(IS_TIM_LIST6_PERIPH(TIMx)); + assert_param(IS_TIM_REMAP(TIM_Remap)); + + /* Set the Timer remapping configuration */ + TIMx->OR = TIM_Remap; +} +/** + * @} + */ + +/** + * @brief Configure the TI1 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14 + * to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input and set the filter */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_IC1F); + tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM + * peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 4); + + /* Select the Input and set the filter */ + tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); + tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12); + tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 8); + + /* Select the Input and set the filter */ + tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR2_IC3F); + tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4)); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection, + uint16_t TIM_ICFilter) +{ + uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + tmp = (uint16_t)(TIM_ICPolarity << 12); + + /* Select the Input and set the filter */ + tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F); + tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8); + tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= (uint16_t)~(TIM_CCER_CC4P | TIM_CCER_CC4NP); + tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/IAR/settings/task01.Debug.cspy.bat b/IAR/settings/task01.Debug.cspy.bat new file mode 100644 index 0000000..eed145b --- /dev/null +++ b/IAR/settings/task01.Debug.cspy.bat @@ -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 \ No newline at end of file diff --git a/IAR/settings/task01.Debug.cspy.ps1 b/IAR/settings/task01.Debug.cspy.ps1 new file mode 100644 index 0000000..c538374 --- /dev/null +++ b/IAR/settings/task01.Debug.cspy.ps1 @@ -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" +} diff --git a/IAR/settings/task01.Debug.driver.xcl b/IAR/settings/task01.Debug.driver.xcl new file mode 100644 index 0000000..29434ea --- /dev/null +++ b/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" + + + + diff --git a/IAR/settings/task01.Debug.general.xcl b/IAR/settings/task01.Debug.general.xcl new file mode 100644 index 0000000..cb1e56c --- /dev/null +++ b/IAR/settings/task01.Debug.general.xcl @@ -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" + + + + diff --git a/IAR/settings/task01.crun b/IAR/settings/task01.crun new file mode 100644 index 0000000..d71ea55 --- /dev/null +++ b/IAR/settings/task01.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/IAR/settings/task01.dbgdt b/IAR/settings/task01.dbgdt new file mode 100644 index 0000000..be47533 --- /dev/null +++ b/IAR/settings/task01.dbgdt @@ -0,0 +1,1044 @@ + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + 34066 + 34067 + 34068 + 34069 + 34070 + 34071 + 34072 + 34073 + 34074 + 34075 + 34076 + 34077 + 34078 + 34079 + 34080 + 34081 + 34082 + 34083 + 34084 + 34085 + 34086 + 34087 + 34088 + 34089 + 34090 + 34091 + 34092 + 34093 + 34094 + 34095 + 34096 + 34097 + 34098 + 34099 + 34100 + 34101 + 34102 + 34103 + 34104 + 34105 + 34106 + 34107 + 34108 + + + + + 34001 + 0 + + + + + 34390 + 34323 + 34398 + 34400 + 34397 + 34320 + 34321 + 34324 + 0 + + + + + 37459 + 37460 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33055 + 33056 + 33094 + 0 + + + + + Disassembly + _I0 + + + 500 + 20 + + + 1 + 1 + + + 4 + 0 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 200000000900108600000E0000000C810000010000001F810000010000000E810000010000001486000001000000118600000100000002840000010000001084000001000000468100000C000000 + + + 0000 + 0000 + + + 0 + 0A0000000A0000006E0000006E000000 + 00000000AE02000056050000C1020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34052 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34053 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 4294967295 + 000000004F0100005605000010020000 + 000000003801000056050000F9010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34054 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34064 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34070 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34071 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34072 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34092 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34103 + 000000001700000022010000C8000000 + 04000000150200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34055 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34056 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34057 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34058 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34060 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34061 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34062 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34063 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 00000000170000000601000078010000 + 500400003200000056050000F9010000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + 34066 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34067 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34068 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34069 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34073 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34074 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34075 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34076 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34077 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34078 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34079 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34080 + 000000001700000022010000D8000000 + 040000005001000052050000DF010000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34081 + 000000001700000022010000D8000000 + 040000005001000052050000DF010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34082 + 000000001700000022010000D8000000 + 040000005001000052050000DF010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34083 + 000000001700000022010000D8000000 + 040000005001000052050000DF010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34084 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34085 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34086 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34087 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34088 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34089 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34090 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34091 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34093 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34094 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34095 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34096 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34097 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34098 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34099 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34100 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34101 + 0000000017000000AE010000D8000000 + 0000000000000000AE010000C1000000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34102 + 0000000017000000AE010000D8000000 + 0000000000000000AE010000C1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34104 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34105 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34106 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34107 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34108 + 00000000170000000601000078010000 + 000000003200000006010000F9010000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 0000000060000000000000000010000001000000FFFFFFFFFFFFFFFF06010000320000000A010000F90100000100000002000010040000000100000000000000000000003C85000000000000000000000000000000000000010000003C850000010000003C850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003B85000000000000000000000000000000000000010000003B850000010000003B850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003A85000000000000000000000000000000000000010000003A850000010000003A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000398500000000000000000000000000000000000001000000398500000100000039850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000388500000000000000000000000000000000000001000000388500000100000038850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000368500000000000000000000000000000000000001000000368500000100000036850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000358500000000000000000000000000000000000001000000358500000100000035850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000348500000000000000000000000000000000000001000000348500000100000034850000000000000020000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000338500000000000000000000000000000000000001000000338500000100000033850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000328500000000000000000000000000000000000001000000328500000100000032850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000318500000000000000000000000000000000000001000000318500000100000031850000000000000010000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000308500000000000000000000000000000000000001000000308500000100000030850000000000000010000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000002F85000000000000000000000000000000000000010000002F850000010000002F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002E85000000000000000000000000000000000000010000002E850000010000002E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002D85000000000000000000000000000000000000010000002D850000010000002D850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000002B85000000000000000000000000000000000000010000002B850000010000002B850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000002A85000000000000000000000000000000000000010000002A850000010000002A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000298500000000000000000000000000000000000001000000298500000100000029850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000288500000000000000000000000000000000000001000000288500000100000028850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000278500000000000000000000000000000000000001000000278500000100000027850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000268500000000000000000000000000000000000001000000268500000100000026850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000258500000000000000000000000000000000000001000000258500000100000025850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000248500000000000000000000000000000000000001000000248500000100000024850000000000000080000000000000FFFFFFFFFFFFFFFF00000000340100005605000038010000000000000100000004000000010000000000000000000000FFFFFFFF0400000020850000218500002285000023850000FFFF02000B004354616262656450616E650080000000000000000000004F0100005605000010020000000000003801000056050000F9010000000000004080004604000000FFFEFF084D0065006D006F007200790020003100000000002085000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003200000000002185000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003300000000002285000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003400000000002385000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF2085000001000000FFFFFFFF20850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000001F85000000000000000000000000000000000000010000001F850000010000001F850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000001E85000000000000000000000000000000000000010000001E850000010000001E850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000001D85000000000000000000000000000000000000010000001D850000010000001D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000001C85000000000000000000000000000000000000010000001C850000010000001C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000001B85000000000000000000000000000000000000010000001B850000010000001B850000000000000020000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000001A85000000000000000000000000000000000000010000001A850000010000001A850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000198500000000000000000000000000000000000001000000198500000100000019850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000158500000000000000000000000000000000000001000000158500000100000015850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000148500000000000000000000000000000000000001000000148500000100000014850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000138500000000000000000000000000000000000001000000138500000100000013850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000128500000000000000000000000000000000000001000000128500000100000012850000000000000040000001000000FFFFFFFFFFFFFFFF4C0400003200000050040000F9010000010000000200001004000000010000000000000000000000118500000000000000000000000000000000000001000000118500000100000011850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000E85000000000000000000000000000000000000010000000E850000010000000E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000B85000000000000000000000000000000000000010000000B850000010000000B850000000000000020000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000A85000000000000000000000000000000000000010000000A850000010000000A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000098500000000000000000000000000000000000001000000098500000100000009850000000000000010000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000088500000000000000000000000000000000000001000000088500000100000008850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000001000000FFFFFFFFFFFFFFFF00000000F901000056050000FD010000010000000100001004000000010000000000000000000000FFFFFFFF0700000006850000108500001685000017850000188500002C8500003785000001800080000001000000000000001402000056050000C502000000000000FD01000056050000AE020000000000004080005607000000FFFEFF054200750069006C006400010000000685000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000001085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000001685000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000001785000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000001885000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000002C85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000003785000001000000FFFFFFFFFFFFFFFF01000000000000000000000000000000000000000000000001000000FFFFFFFF0685000001000000FFFFFFFF06850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED18400000000000020000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + 2B04000000000000590400001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Debug + 00200000010000000800FFFF01001100434D4643546F6F6C426172427574746F6E568600000000040035000000FFFEFF0000000000000000000000000001000000010000000180138600000000040031000000FFFEFF00000000000000000000000000010000000100000001805E8600000000040037000000FFFEFF0000000000000000000000000001000000010000000180608600000000040039000000FFFEFF00000000000000000000000000010000000100000001805D8600000000040036000000FFFEFF000000000000000000000000000100000001000000018010860000000004002F000000FFFEFF0000000000000000000000000001000000010000000180118600000000000030000000FFFEFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E148600000000040032000000FFFEFF205200650073006500740020007400680065002000640065006200750067006700650064002000700072006F006700720061006D000A00520065007300650074000000000000000000000000000100000001000000000000000000000001000000060009802087000000000000FFFFFFFFFFFEFF06530079007300740065006D000100000000000000000000000100000001000000000000000000000001000000000009802387000000000000FFFFFFFFFFFEFF0443006F00720065000100000000000000000000000100000001000000000000000000000001000000000009802487000000000000FFFFFFFFFFFEFF0853006F006600740077006100720065000100000000000000000000000100000001000000000000000000000001000000000009802187000000000000FFFFFFFFFFFEFF12480061007200640077006100720065002000720065007300650074002000700069006E000100000000000000000000000100000001000000000000000000000001000000000009800000000000000400FFFFFFFFFFFEFF000000000000000000000000000100000001000000000000000000000001000000000009801986000000000000FFFFFFFFFFFEFF000100000000000000000000000100000001000000000000000000000001000000000000000000FFFEFF0544006500620075006700C6000000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 1503000000000000F10300001A000000 + 8192 + 0 + 0 + 198 + 0 + + + 1 + + + Trace + 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6E53920000000004008A000000FFFEFF03450054004D0000000000000000000000000001000000010000000180549200000000000025000000FFFEFF03530057004F00000000000000000000000000010000000100000000000000FFFEFF05540072006100630065002F000000 + + + 34050 + 0A0000000A0000006E0000006E000000 + F1030000000000002B0400001A000000 + 8192 + 0 + 0 + 47 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000067000000FFFEFF000000000000000000000000000100000001000000018001E100000000000068000000FFFEFF000000000000000000000000000100000001000000018003E10000000000006A000000FFFEFF000000000000000000000000000100000001000000018000810000000000004B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000000006D000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000000006F000000FFFEFF000000000000000000000000000100000001000000018022E10000000000006E000000FFFEFF000000000000000000000000000100000001000000018025E100000000040071000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000000074000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040075000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6E4281000000000000FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004005E000000FFFEFF000000000000000000000000000100000001000000018024E100000000000070000000FFFEFF000000000000000000000000000100000001000000018028E100000000040072000000FFFEFF000000000000000000000000000100000001000000018029E100000000000073000000FFFEFF000000000000000000000000000100000001000000018002810000000000004D000000FFFEFF0000000000000000000000000001000000010000000180298100000000000062000000FFFEFF0000000000000000000000000001000000010000000180278100000000000060000000FFFEFF0000000000000000000000000001000000010000000180288100000000000061000000FFFEFF00000000000000000000000000010000000100000001801D810000000004005A000000FFFEFF00000000000000000000000000010000000100000001801E810000000004005B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B8100000000000051000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000052000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000066000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001801F810000000000005C000000FFFEFF000000000000000000000000000100000001000000018020810000000000005D000000FFFEFF0000000000000000000000000001000000010000000180468100000000020064000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00FF020000 + + + 34051 + 0A0000000A0000006E0000006E000000 + 0000000000000000150300001A000000 + 8192 + 0 + 0 + 767 + 0 + + + 1 + + + + diff --git a/IAR/settings/task01.dnx b/IAR/settings/task01.dnx new file mode 100644 index 0000000..96f9180 --- /dev/null +++ b/IAR/settings/task01.dnx @@ -0,0 +1,155 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 1 + + + 1 + 0 + 1 + 0 + 1 + + + 0 + 1 + + + 10000000 + 0 + 1 + + + 35452557 + + 0 + 0 + _ 0 + _ 0 + + + 1117100520 + + + _ 0 + _ 0 + + + 0 + 1 + + + 0 + 0 + 0 + + + 0 + + + 0 + 168000000 + 0 + 2000000 + 2000000 + 84 + 0 + 0 + 1 + 15 + 0 + 0 + 0 + 0 + 0 + $PROJ_DIR$\ITM.log + + + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 1 + 0 + 1 + + + 0 + 0 + 1 + 0 + 1 + 0 + + + Ch3 + 0 0 1 + Ch2 + 0 0 1 + Ch1 + 0 0 1 + Ch0 + 0 0 1 + 0 + 0 + 1 + 0 + 1 + 0 + + + _ 0 + _ "" + + + _ 0 + _ "" + _ 0 + + + 0 + 3 + 0 + 0 + + + + 0 + + + 1 + + + 0 + + + 0 + + + 0 + 0 + + diff --git a/IAR/settings/task01.wsdt b/IAR/settings/task01.wsdt new file mode 100644 index 0000000..219cb41 --- /dev/null +++ b/IAR/settings/task01.wsdt @@ -0,0 +1,413 @@ + + + + + task01/Debug + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33038 + 33039 + 0 + + + + 21 + 993 + 264 + 66 + 2 + F:\XinJe\UCOS\TrainCamp_YuJingYuan_Ucos\IAR\BuildLog.log + 0 + -1 + + + + 152 + 30 + 30 + 30 + + + task01 + task01/APP + task01/UCOS + + + + 24 + 1309 + 2 + + 0 + -1 + + + 4 + 0 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 15000000090010860000010000000C810000050000001F810000010000000E8100000C00000014860000010000001186000001000000028400000100000010840000030000004681000001000000 + + + 0D007784000007840000FFFFFFFF808C00000D8400000F8400000884000054840000328100001C8100000984000044D5000053840000 + 1500048400004C000000318400005300000023920000000000000F81000023000000208100002B0000000C81000020000000068400004E000000038400004B000000008400004800000030840000520000000E840000500000000E810000220000001F8100002A0000000B8100001F000000058400004D000000D18400000C000000028400004A000000108400005100000032840000540000000A8400004F0000000D81000021000000 + + + 0 + 0A0000000A0000006E0000006E000000 + 00000000AE02000056050000C1020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 4294967295 + 000000003502000056050000C5020000 + 000000001E02000056050000AE020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34050 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34053 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34055 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34056 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34063 + 000000001700000022010000C8000000 + 04000000360200005205000094020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34052 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34057 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34058 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34060 + 00000000170000000601000078010000 + 0000000032000000E00000001A020000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34061 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34062 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34064 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 0000000010000000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000E85000000000000000000000000000000000000010000000E850000010000000E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000010000001000000FFFFFFFFFFFFFFFFE000000032000000E40000001A0200000100000002000010040000000100000000000000B60400000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000A85000000000000000000000000000000000000010000000A850000010000000A850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000098500000000000000000000000000000000000001000000098500000100000009850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000080000001000000FFFFFFFFFFFFFFFF000000001A020000560500001E020000010000000100001004000000010000006AFEFFFF9B000000FFFFFFFF0700000002850000058500000685000007850000088500000B8500000F850000FFFF02000B004354616262656450616E650080000001000000000000003502000056050000C5020000000000001E02000056050000AE020000000000004080005607000000FFFEFF054200750069006C006400010000000285000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000585000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000685000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000785000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000F85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0285000001000000FFFFFFFF02850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000000000000C000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + FE020000000000002C0300001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000035000000FFFEFF000000000000000000000000000100000001000000018001E100000000000036000000FFFEFF000000000000000000000000000100000001000000018003E100000000000038000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000000003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004003D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000000042000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040043000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6E4281000000000000FFFFFFFFFFFEFF0001000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000100FFFEFF075000420034005F004E0075006D0000000000018021810000000004002C000000FFFEFF000000000000000000000000000100000001000000018024E10000000000003E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040040000000FFFEFF000000000000000000000000000100000001000000018029E100000000000041000000FFFEFF000000000000000000000000000100000001000000018002810000000000001B000000FFFEFF0000000000000000000000000001000000010000000180298100000000000030000000FFFEFF000000000000000000000000000100000001000000018027810000000000002E000000FFFEFF000000000000000000000000000100000001000000018028810000000000002F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040028000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040029000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000000001F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000020000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000000000022000000FFFEFF00000000000000000000000000010000000100000001800F8100000000000023000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 0000000000000000FE0200001A000000 + 8192 + 0 + 0 + 744 + 0 + + + 1 + + + + + 0100000003000000010000000000000000000000010000000100000002000000000000000100000001000000000000002800000028000000010000000A0000000000000001000000FFFEFF162400570053005F0044004900520024005C002E002E005C004100500050005C006D00610069006E002E00630001000000FFFF010014004966436F6E74656E7453746F72616765496D706CFFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003300360031003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0034003600370033003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0034003600370033003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFFFFFEFF192400570053005F0044004900520024005C002E002E005C004100500050005C004C00450044005C006C00650064002E006300010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003200370037003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003200370037003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF056C00650064002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1D2400570053005F0044004900520024005C002E002E005C004100500050005C00640065006C00610079005C00640065006C00610079002E006300010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003100360038003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0035003900360032003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0035003900360032003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF07640065006C00610079002E00630000000000FFFFFFFFFFFFFFFFFFFEFF192400570053005F0044004900520024005C002E002E005C004100500050005C007300790073005C007300790073002E006300010000000180FFFEFF00FFFEFFFF23013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00320031003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E00310038003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E00310038003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF057300790073002E00630000000000FFFFFFFFFFFFFFFFFFFEFF192400570053005F0044004900520024005C002E002E005C004100500050005C007300790073005C007300790073002E006800010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E00350039003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E00350039003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF057300790073002E00680000000000FFFFFFFFFFFFFFFFFFFEFF1D2400570053005F0044004900520024005C002E002E005C004100500050005C00540049004D00450052005C00740069006D00650072002E006300010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0034003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003900340035003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003900340035003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF07740069006D00650072002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C004100500050005C0045005800540049005C0065007800740069002E006300010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E00350039003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E00350039003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0665007800740069002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1E2400570053005F0044004900520024005C002E002E005C004100500050005C00730074006D003300320066003400780078005F00690074002E006300010000000180FFFEFF00FFFEFFFF20013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0E730074006D003300320066003400780078005F00690074002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C004100500050005C0045005800540049005C0065007800740069002E006800010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003300390031003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003400350032003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0665007800740069002E00680000000000FFFFFFFFFFFFFFFFFFFEFF1D2400570053005F0044004900520024005C002E002E005C004100500050005C00540049004D00450052005C00740069006D00650072002E006800010000000180FFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003200330030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003200330030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF07740069006D00650072002E00680000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000100000002000000E4000000490000005605000031020000 + + + + diff --git a/IAR/startup_stm32f40_41xxx.s b/IAR/startup_stm32f40_41xxx.s new file mode 100644 index 0000000..f523fb3 --- /dev/null +++ b/IAR/startup_stm32f40_41xxx.s @@ -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****/ diff --git a/IAR/task01.dep b/IAR/task01.dep new file mode 100644 index 0000000..44c4658 --- /dev/null +++ b/IAR/task01.dep @@ -0,0 +1,812 @@ + + + 4 + 689384112 + + Debug + + $PROJ_DIR$\..\UCOS\CORE\os_tmr.c + $TOOLKIT_DIR$\inc\c\yvals.h + $PROJ_DIR$\..\UCOS\CORE\os_core.c + $PROJ_DIR$\..\APP\main.c + $PROJ_DIR$\..\APP\sys\sys.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_gpio.h + $PROJ_DIR$\Debug\Obj\os_time.__cstat.et + $PROJ_DIR$\..\UCOS\CORE\os_mbox.c + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_exti.c + $PROJ_DIR$\..\UCOS\CORE\os_q.c + $PROJ_DIR$\..\UCOS\PORT\os_cpu.h + $PROJ_DIR$\..\UCOS\CORE\os_sem.c + $PROJ_DIR$\..\UCOS\PORT\os_cpu_a.asm + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_iwdg.h + $PROJ_DIR$\..\UCOS\CONFIG\os_cfg.h + $PROJ_DIR$\..\APP\system_stm32f4xx.c + $PROJ_DIR$\..\UCOS\CORE\os_time.c + $PROJ_DIR$\..\UCOS\CORE\os_mem.c + $PROJ_DIR$\..\UCOS\PORT\os_cpu_c.c + $PROJ_DIR$\..\UCOS\CORE\os_mutex.c + $PROJ_DIR$\..\APP\sys\sys.c + $PROJ_DIR$\..\APP\TIMER\timer.c + $PROJ_DIR$\..\APP\stm32f4xx_it.c + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_gpio.c + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_syscfg.c + $PROJ_DIR$\startup_stm32f40_41xxx.s + $PROJ_DIR$\..\DRIVER\src\misc.c + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_rcc.c + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_tim.c + $PROJ_DIR$\..\UCOS\CORE\os_flag.c + $PROJ_DIR$\..\UCOS\CONFIG\includes.h + $PROJ_DIR$\..\UCOS\CORE\os_task.c + $PROJ_DIR$\..\APP\delay\delay.c + $PROJ_DIR$\..\APP\EXTI\exti.c + $PROJ_DIR$\..\APP\LED\led.c + $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.__cstat.et + $PROJ_DIR$\Debug\Obj\timer.xcl + $PROJ_DIR$\Debug\Obj\timer.o + $PROJ_DIR$\Debug\Obj\os_mbox.xcl + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_flash.h + $PROJ_DIR$\Debug\Obj\os_mem.__cstat.et + $PROJ_DIR$\Debug\Obj\os_sem.__cstat.et + $PROJ_DIR$\Debug\Obj\sys.__cstat.et + $TOOLKIT_DIR$\inc\c\stdint.h + $PROJ_DIR$\Debug\Obj\main.o + $PROJ_DIR$\..\APP\system_stm32f4xx.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.xcl + $PROJ_DIR$\Debug\Obj\os_q.__cstat.et + $PROJ_DIR$\Debug\Obj\os_mutex.o + $PROJ_DIR$\..\APP\stm32f4xx_conf.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dbgmcu.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.__cstat.et + $PROJ_DIR$\Debug\Obj\os_flag.o + $PROJ_DIR$\Debug\Obj\os_cpu_a.o + $PROJ_DIR$\Debug\Obj\os_time.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.__cstat.et + $PROJ_DIR$\Debug\Obj\os_cpu_c.xcl + $PROJ_DIR$\Debug\Obj\startup_stm32f40_41xxx.o + $PROJ_DIR$\Debug\Obj\os_core.o + $PROJ_DIR$\Debug\Obj\os_mbox.__cstat.et + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.o + $PROJ_DIR$\Debug\Obj\sys.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_it.o + $PROJ_DIR$\Debug\Obj\main.xcl + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.xcl + $PROJ_DIR$\Debug\Obj\os_cpu_c.__cstat.et + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_adc.h + $TOOLKIT_DIR$\inc\c\iccarm_builtin.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_pwr.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.o + $PROJ_DIR$\Debug\Obj\os_tmr.__cstat.et + $PROJ_DIR$\..\CMSIS\core_cm4_simd.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rcc.h + $PROJ_DIR$\Debug\Obj\os_cpu_c.o + $TOOLKIT_DIR$\inc\c\ycheck.h + $PROJ_DIR$\Debug\Obj\os_task.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.o + $PROJ_DIR$\Debug\Obj\sys.xcl + $TOOLKIT_DIR$\inc\c\cmsis_iar.h + $TOOLKIT_DIR$\inc\c\DLib_Product.h + $PROJ_DIR$\Debug\Obj\misc.xcl + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dma.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_syscfg.o + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_crc.h + $TOOLKIT_DIR$\inc\c\DLib_Defaults.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_exti.h + $PROJ_DIR$\Debug\Obj\os_flag.__cstat.et + $PROJ_DIR$\Debug\Obj\os_core.__cstat.et + $PROJ_DIR$\..\APP\EXTI\exti.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_i2c.h + $PROJ_DIR$\..\CMSIS\core_cmInstr.h + $PROJ_DIR$\..\CMSIS\core_cm4.h + $PROJ_DIR$\..\CMSIS\core_cmFunc.h + $PROJ_DIR$\..\APP\stm32f4xx.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_it.xcl + $TOOLKIT_DIR$\inc\c\DLib_Config_Full.h + $PROJ_DIR$\Debug\Obj\os_mutex.__cstat.et + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_wwdg.h + $TOOLKIT_DIR$\lib\shb_l.a + $PROJ_DIR$\Debug\Obj\stm32f4xx_tim.xcl + $PROJ_DIR$\Debug\Exe\task01.hex + $TOOLKIT_DIR$\lib\dl7M_tlf.a + $PROJ_DIR$\..\APP\LED\led.h + $PROJ_DIR$\Debug\Obj\misc.o + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_usart.h + $PROJ_DIR$\..\APP\TIMER\timer.h + $TOOLKIT_DIR$\lib\rt7M_tl.a + $PROJ_DIR$\..\APP\main.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.o + $PROJ_DIR$\Debug\Obj\main.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_rcc.xcl + $PROJ_DIR$\Debug\Obj\led.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.__cstat.et + $TOOLKIT_DIR$\inc\c\DLib_Product_string.h + $PROJ_DIR$\Debug\Obj\system_stm32f4xx.__cstat.et + $PROJ_DIR$\Debug\Obj\delay.__cstat.et + $TOOLKIT_DIR$\lib\m7M_tls.a + $TOOLKIT_DIR$\config\linker\ST\stm32f407xG.icf + $PROJ_DIR$\..\UCOS\CORE\ucos_ii.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_hash.h + $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.xcl + $PROJ_DIR$\Debug\Obj\timer.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_gpio.o + $PROJ_DIR$\Debug\Obj\stm32f4xx_exti.xcl + $PROJ_DIR$\Debug\List\task01.map + $PROJ_DIR$\Debug\Obj\misc.__cstat.et + $PROJ_DIR$\Debug\Obj\stm32f4xx_it.__cstat.et + $PROJ_DIR$\Debug\Obj\exti.__cstat.et + $TOOLKIT_DIR$\inc\c\stdarg.h + $TOOLKIT_DIR$\inc\c\stdlib.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dac.h + $PROJ_DIR$\Debug\Obj\led.xcl + $PROJ_DIR$\Debug\Obj\os_task.xcl + $TOOLKIT_DIR$\inc\c\string.h + $PROJ_DIR$\..\APP\stm32f4xx_it.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_fsmc.h + $PROJ_DIR$\..\APP\delay\delay.h + $PROJ_DIR$\Debug\Obj\os_core.xcl + $PROJ_DIR$\Debug\Obj\os_sem.o + $PROJ_DIR$\Debug\Obj\exti.xcl + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_sdio.h + $TOOLKIT_DIR$\inc\c\stdio.h + $TOOLKIT_DIR$\inc\c\ctype.h + $PROJ_DIR$\Debug\Obj\delay.xcl + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_syscfg.h + $TOOLKIT_DIR$\inc\c\DLib_Product_stdlib.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_can.h + $PROJ_DIR$\Debug\Obj\task01.pbd + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rtc.h + $PROJ_DIR$\Debug\Obj\led.o + $TOOLKIT_DIR$\inc\c\ysizet.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_spi.h + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_cryp.h + $PROJ_DIR$\Debug\Obj\os_sem.xcl + $PROJ_DIR$\Debug\Obj\os_mbox.o + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_dcmi.h + $PROJ_DIR$\Debug\Obj\os_q.o + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_rng.h + $PROJ_DIR$\Debug\Obj\exti.o + $PROJ_DIR$\Debug\Obj\os_time.xcl + $PROJ_DIR$\Debug\Exe\task01.out + $PROJ_DIR$\..\DRIVER\inc\stm32f4xx_tim.h + $PROJ_DIR$\Debug\Obj\os_q.xcl + $PROJ_DIR$\..\DRIVER\inc\misc.h + $PROJ_DIR$\Debug\Obj\os_tmr.o + $PROJ_DIR$\Debug\Obj\os_mutex.xcl + $PROJ_DIR$\Debug\Obj\os_tmr.xcl + $PROJ_DIR$\Debug\Obj\delay.o + $PROJ_DIR$\Debug\Obj\os_task.o + $PROJ_DIR$\Debug\Obj\os_mem.o + $PROJ_DIR$\Debug\Obj\os_mem.xcl + $PROJ_DIR$\Debug\Obj\os_flag.xcl + + + [ROOT_NODE] + + + ILINK + 161 125 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_tmr.c + + + ICCARM + 165 + + + __cstat + 71 + + + BICOMP + 167 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_core.c + + + ICCARM + 59 + + + __cstat + 88 + + + BICOMP + 138 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\main.c + + + ICCARM + 44 + + + __cstat + 110 + + + BICOMP + 64 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_mbox.c + + + ICCARM + 155 + + + __cstat + 60 + + + BICOMP + 38 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_exti.c + + + ICCARM + 109 + + + __cstat + 113 + + + BICOMP + 124 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_q.c + + + ICCARM + 157 + + + __cstat + 47 + + + BICOMP + 163 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_sem.c + + + ICCARM + 139 + + + __cstat + 41 + + + BICOMP + 154 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\PORT\os_cpu_a.asm + + + AARM + 54 + + + + + $PROJ_DIR$\..\APP\system_stm32f4xx.c + + + ICCARM + 61 + + + __cstat + 115 + + + BICOMP + 65 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_time.c + + + ICCARM + 55 + + + __cstat + 6 + + + BICOMP + 160 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_mem.c + + + ICCARM + 170 + + + __cstat + 40 + + + BICOMP + 171 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\PORT\os_cpu_c.c + + + ICCARM + 74 + + + __cstat + 66 + + + BICOMP + 57 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_mutex.c + + + ICCARM + 48 + + + __cstat + 97 + + + BICOMP + 166 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\sys\sys.c + + + ICCARM + 62 + + + __cstat + 42 + + + BICOMP + 78 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\TIMER\timer.c + + + ICCARM + 37 + + + __cstat + 122 + + + BICOMP + 36 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\stm32f4xx_it.c + + + ICCARM + 63 + + + __cstat + 127 + + + BICOMP + 95 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_gpio.c + + + ICCARM + 123 + + + __cstat + 51 + + + BICOMP + 121 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_syscfg.c + + + ICCARM + 83 + + + __cstat + 56 + + + BICOMP + 46 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\startup_stm32f40_41xxx.s + + + AARM + 58 + + + + + $PROJ_DIR$\..\DRIVER\src\misc.c + + + ICCARM + 104 + + + __cstat + 126 + + + BICOMP + 81 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_rcc.c + + + ICCARM + 77 + + + __cstat + 35 + + + BICOMP + 111 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_tim.c + + + ICCARM + 70 + + + __cstat + 52 + + + BICOMP + 100 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_flag.c + + + ICCARM + 53 + + + __cstat + 87 + + + BICOMP + 172 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\UCOS\CORE\os_task.c + + + ICCARM + 169 + + + __cstat + 76 + + + BICOMP + 133 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\delay\delay.c + + + ICCARM + 168 + + + __cstat + 116 + + + BICOMP + 144 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\EXTI\exti.c + + + ICCARM + 159 + + + __cstat + 128 + + + BICOMP + 140 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\..\APP\LED\led.c + + + ICCARM + 150 + + + __cstat + 112 + + + BICOMP + 132 + + + + + ICCARM + 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 + + + + + $PROJ_DIR$\Debug\Exe\task01.out + + + OBJCOPY + 101 + + + ILINK + 125 + + + + + ILINK + 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 + + + + + + Release + + + [MULTI_TOOL] + ILINK + + + diff --git a/IAR/task01.ewd b/IAR/task01.ewd new file mode 100644 index 0000000..b37674e --- /dev/null +++ b/IAR/task01.ewd @@ -0,0 +1,2966 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 6 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/IAR/task01.ewp b/IAR/task01.ewp new file mode 100644 index 0000000..5014198 --- /dev/null +++ b/IAR/task01.ewp @@ -0,0 +1,2228 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + APP + + $PROJ_DIR$\..\APP\delay\delay.c + + + $PROJ_DIR$\..\APP\EXTI\exti.c + + + $PROJ_DIR$\..\APP\LED\led.c + + + $PROJ_DIR$\..\APP\main.c + + + $PROJ_DIR$\..\APP\stm32f4xx_it.c + + + $PROJ_DIR$\..\APP\sys\sys.c + + + $PROJ_DIR$\..\APP\system_stm32f4xx.c + + + $PROJ_DIR$\..\APP\TIMER\timer.c + + + + CMSIS + + $PROJ_DIR$\startup_stm32f40_41xxx.s + + + + DRIVER + + $PROJ_DIR$\..\DRIVER\src\misc.c + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_exti.c + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_gpio.c + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_rcc.c + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_syscfg.c + + + $PROJ_DIR$\..\DRIVER\src\stm32f4xx_tim.c + + + + UCOS + + CONFIG + + $PROJ_DIR$\..\UCOS\CONFIG\includes.h + + + $PROJ_DIR$\..\UCOS\CONFIG\os_cfg.h + + + + CORE + + $PROJ_DIR$\..\UCOS\CORE\os_core.c + + + $PROJ_DIR$\..\UCOS\CORE\os_flag.c + + + $PROJ_DIR$\..\UCOS\CORE\os_mbox.c + + + $PROJ_DIR$\..\UCOS\CORE\os_mem.c + + + $PROJ_DIR$\..\UCOS\CORE\os_mutex.c + + + $PROJ_DIR$\..\UCOS\CORE\os_q.c + + + $PROJ_DIR$\..\UCOS\CORE\os_sem.c + + + $PROJ_DIR$\..\UCOS\CORE\os_task.c + + + $PROJ_DIR$\..\UCOS\CORE\os_time.c + + + $PROJ_DIR$\..\UCOS\CORE\os_tmr.c + + + + PORT + + $PROJ_DIR$\..\UCOS\PORT\os_cpu.h + + + $PROJ_DIR$\..\UCOS\PORT\os_cpu_a.asm + + + $PROJ_DIR$\..\UCOS\PORT\os_cpu_c.c + + + + diff --git a/IAR/task01.eww b/IAR/task01.eww new file mode 100644 index 0000000..c92164e --- /dev/null +++ b/IAR/task01.eww @@ -0,0 +1,7 @@ + + + + $WS_DIR$\task01.ewp + + + diff --git a/UCOS/CONFIG/includes.h b/UCOS/CONFIG/includes.h new file mode 100644 index 0000000..a233464 --- /dev/null +++ b/UCOS/CONFIG/includes.h @@ -0,0 +1,56 @@ +/* +************************************************************************************************ +Ö÷ÒªµÄ°üº¬Îļþ + +ÎÄ ¼þ: INCLUDES.C ucos°üº¬Îļþ +×÷ Õß: Jean J. Labrosse +************************************************************************************************ +*/ + +#ifndef __INCLUDES_H__ +#define __INCLUDES_H__ +#include +#include +#include +#include +#include + +#include "ucos_ii.h" +#include "os_cpu.h" +#include "os_cfg.h" + +#include + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UCOS/CONFIG/os_cfg.h b/UCOS/CONFIG/os_cfg.h new file mode 100644 index 0000000..264b6e7 --- /dev/null +++ b/UCOS/CONFIG/os_cfg.h @@ -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 + diff --git a/UCOS/CORE/os_core.c b/UCOS/CORE/os_core.c new file mode 100644 index 0000000..c796b80 --- /dev/null +++ b/UCOS/CORE/os_core.c @@ -0,0 +1,2028 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* CORE FUNCTIONS +* +* (c) Copyright 1992-2009, Micrium, Weston, FL +* All Rights Reserved +* +* File : OS_CORE.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 +#define OS_GLOBALS +#include +#endif + +/* +********************************************************************************************************* +* PRIORITY RESOLUTION TABLE +* +* Note: Index into table is bit pattern to resolve highest priority +* Indexed value corresponds to highest priority bit position (i.e. 0..7) +********************************************************************************************************* +*/ + +INT8U const OSUnMapTbl[256] = { + 0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x00 to 0x0F */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x10 to 0x1F */ + 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x20 to 0x2F */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x30 to 0x3F */ + 6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x40 to 0x4F */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x50 to 0x5F */ + 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x60 to 0x6F */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x70 to 0x7F */ + 7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x80 to 0x8F */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x90 to 0x9F */ + 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xA0 to 0xAF */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xB0 to 0xBF */ + 6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xC0 to 0xCF */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xD0 to 0xDF */ + 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xE0 to 0xEF */ + 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u /* 0xF0 to 0xFF */ +}; + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_InitEventList(void); + +static void OS_InitMisc(void); + +static void OS_InitRdyList(void); + +static void OS_InitTaskIdle(void); + +#if OS_TASK_STAT_EN > 0u +static void OS_InitTaskStat(void); +#endif + +static void OS_InitTCBList(void); + +static void OS_SchedNew(void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function is used to obtain the name assigned to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, the actual +* type is irrelevant. +* +* pname is a pointer to a pointer to an ASCII string that will receive the name of the semaphore, +* mutex, mailbox or queue. +* +* 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_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* OS_ERR_NAME_GET_ISR if you are trying to call this function from an ISR +* +* Returns : The length of the string or 0 if the 'pevent' is a NULL pointer. +********************************************************************************************************* +*/ + +#if (OS_EVENT_EN) && (OS_EVENT_NAME_EN > 0u) +INT8U OSEventNameGet (OS_EVENT *pevent, + 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 (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + 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); + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return (0u); + } + OS_ENTER_CRITICAL(); + *pname = pevent->OSEventName; + len = OS_StrLen(*pname); + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A SEMAPHORE, MUTEX, MAILBOX or QUEUE +* +* Description: This function assigns a name to a semaphore, mutex, mailbox or queue. +* +* Arguments : pevent is a pointer to the event group. 'pevent' can point either to a semaphore, +* a mutex, a mailbox or a queue. Where this function is concerned, it doesn't +* matter the actual type. +* +* pname is a pointer to an ASCII string that will be used as the name of the semaphore, +* mutex, mailbox or queue. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to the proper event +* control block type. +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PEVENT_NULL if you passed a NULL pointer for 'pevent' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if (OS_EVENT_EN) && (OS_EVENT_NAME_EN > 0u) +void OSEventNameSet (OS_EVENT *pevent, + 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 (pevent == (OS_EVENT *)0) { /* Is 'pevent' a NULL pointer? */ + *perr = OS_ERR_PEVENT_NULL; + 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; + } + switch (pevent->OSEventType) { + case OS_EVENT_TYPE_SEM: + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + break; + + default: + *perr = OS_ERR_EVENT_TYPE; + return; + } + OS_ENTER_CRITICAL(); + pevent->OSEventName = pname; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PEND ON MULTIPLE EVENTS +* +* Description: This function waits for multiple events. If multiple events are ready at the start of the +* pend call, then all available events are returned as ready. If the task must pend on the +* multiple events, then only the first posted or aborted event is returned as ready. +* +* Arguments : pevents_pend is a pointer to a NULL-terminated array of event control blocks to wait for. +* +* pevents_rdy is a pointer to an array to return which event control blocks are available +* or ready. The size of the array MUST be greater than or equal to the size +* of the 'pevents_pend' array, including terminating NULL. +* +* pmsgs_rdy is a pointer to an array to return messages from any available message-type +* events. The size of the array MUST be greater than or equal to the size of +* the 'pevents_pend' array, excluding the terminating NULL. Since NULL +* messages are valid messages, this array cannot be NULL-terminated. Instead, +* every available message-type event returns its messages in the 'pmsgs_rdy' +* array at the same index as the event is returned in the 'pevents_rdy' array. +* All other 'pmsgs_rdy' array indices are filled with NULL messages. +* +* timeout is an optional timeout period (in clock ticks). If non-zero, your task will +* wait for the resources up to the amount of time specified by this argument. +* If you specify 0, however, your task will wait forever for the specified +* events or, until the resources becomes available (or the events occur). +* +* 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 resources +* or, the events you are waiting for occurred; check the +* 'pevents_rdy' array for which events are available. +* OS_ERR_PEND_ABORT The wait on the events was aborted; check the +* 'pevents_rdy' array for which events were aborted. +* OS_ERR_TIMEOUT The events were not received within the specified +* 'timeout'. +* OS_ERR_PEVENT_NULL If 'pevents_pend', 'pevents_rdy', or 'pmsgs_rdy' is a +* NULL pointer. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to an array of semaphores, +* mailboxes, and/or queues. +* 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 when the scheduler is locked. +* +* Returns : > 0 the number of events returned as ready or aborted. +* == 0 if no events are returned as ready because of timeout or upon error. +* +* Notes : 1) a. Validate 'pevents_pend' array as valid OS_EVENTs : +* +* semaphores, mailboxes, queues +* +* b. Return ALL available events and messages, if any +* +* c. Add current task priority as pending to each events's wait list +* Performed in OS_EventTaskWaitMulti() +* +* d. Wait on any of multiple events +* +* e. Remove current task priority as pending from each events's wait list +* Performed in OS_EventTaskRdy(), if events posted or aborted +* +* f. Return any event posted or aborted, if any +* else +* Return timeout +* +* 2) 'pevents_rdy' initialized to NULL PRIOR to all other validation or function handling in +* case of any error(s). +********************************************************************************************************* +*/ +/*$PAGE*/ +#if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)) +INT16U OSEventPendMulti (OS_EVENT **pevents_pend, + OS_EVENT **pevents_rdy, + void **pmsgs_rdy, + INT32U timeout, + INT8U *perr) +{ + OS_EVENT **pevents; + OS_EVENT *pevent; +#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) + OS_Q *pq; +#endif + BOOLEAN events_rdy; + INT16U events_rdy_nbr; + INT8U events_stat; +#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 (pevents_pend == (OS_EVENT **)0) { /* Validate 'pevents_pend' */ + *perr = OS_ERR_PEVENT_NULL; + return (0u); + } + if (*pevents_pend == (OS_EVENT *)0) { /* Validate 'pevents_pend' */ + *perr = OS_ERR_PEVENT_NULL; + return (0u); + } + if (pevents_rdy == (OS_EVENT **)0) { /* Validate 'pevents_rdy' */ + *perr = OS_ERR_PEVENT_NULL; + return (0u); + } + if (pmsgs_rdy == (void **)0) { /* Validate 'pmsgs_rdy' */ + *perr = OS_ERR_PEVENT_NULL; + return (0u); + } +#endif + + *pevents_rdy = (OS_EVENT *)0; /* Init array to NULL in case of errors */ + + pevents = pevents_pend; + pevent = *pevents; + while (pevent != (OS_EVENT *)0) { + switch (pevent->OSEventType) { /* Validate event block types */ +#if (OS_SEM_EN > 0u) + case OS_EVENT_TYPE_SEM: + break; +#endif +#if (OS_MBOX_EN > 0u) + case OS_EVENT_TYPE_MBOX: + break; +#endif +#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) + case OS_EVENT_TYPE_Q: + break; +#endif + + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_FLAG: + default: + *perr = OS_ERR_EVENT_TYPE; + return (0u); + } + pevents++; + pevent = *pevents; + } + + if (OSIntNesting > 0u) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return (0u); + } + if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return (0u); + } + +/*$PAGE*/ + OS_ENTER_CRITICAL(); + events_rdy = OS_FALSE; + events_rdy_nbr = 0u; + events_stat = OS_STAT_RDY; + pevents = pevents_pend; + pevent = *pevents; + while (pevent != (OS_EVENT *)0) { /* See if any events already available */ + switch (pevent->OSEventType) { +#if (OS_SEM_EN > 0u) + case OS_EVENT_TYPE_SEM: + if (pevent->OSEventCnt > 0u) { /* If semaphore count > 0, resource available; */ + pevent->OSEventCnt--; /* ... decrement semaphore, ... */ + *pevents_rdy++ = pevent; /* ... and return available semaphore event */ + events_rdy = OS_TRUE; + *pmsgs_rdy++ = (void *)0; /* NO message returned for semaphores */ + events_rdy_nbr++; + + } else { + events_stat |= OS_STAT_SEM; /* Configure multi-pend for semaphore events */ + } + break; +#endif + +#if (OS_MBOX_EN > 0u) + case OS_EVENT_TYPE_MBOX: + if (pevent->OSEventPtr != (void *)0) { /* If mailbox NOT empty; ... */ + /* ... return available message, ... */ + *pmsgs_rdy++ = (void *)pevent->OSEventPtr; + pevent->OSEventPtr = (void *)0; + *pevents_rdy++ = pevent; /* ... and return available mailbox event */ + events_rdy = OS_TRUE; + events_rdy_nbr++; + + } else { + events_stat |= OS_STAT_MBOX; /* Configure multi-pend for mailbox events */ + } + break; +#endif + +#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) + case OS_EVENT_TYPE_Q: + pq = (OS_Q *)pevent->OSEventPtr; + if (pq->OSQEntries > 0u) { /* If queue NOT empty; ... */ + /* ... return available message, ... */ + *pmsgs_rdy++ = (void *)*pq->OSQOut++; + if (pq->OSQOut == pq->OSQEnd) { /* If OUT ptr at queue end, ... */ + pq->OSQOut = pq->OSQStart; /* ... wrap to queue start */ + } + pq->OSQEntries--; /* Update number of queue entries */ + *pevents_rdy++ = pevent; /* ... and return available queue event */ + events_rdy = OS_TRUE; + events_rdy_nbr++; + + } else { + events_stat |= OS_STAT_Q; /* Configure multi-pend for queue events */ + } + break; +#endif + + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_FLAG: + default: + OS_EXIT_CRITICAL(); + *pevents_rdy = (OS_EVENT *)0; /* NULL terminate return event array */ + *perr = OS_ERR_EVENT_TYPE; + return (events_rdy_nbr); + } + pevents++; + pevent = *pevents; + } + + if ( events_rdy == OS_TRUE) { /* Return any events already available */ + *pevents_rdy = (OS_EVENT *)0; /* NULL terminate return event array */ + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (events_rdy_nbr); + } +/*$PAGE*/ + /* Otherwise, must wait until any event occurs */ + OSTCBCur->OSTCBStat |= events_stat | /* Resource not available, ... */ + OS_STAT_MULTI; /* ... pend on multiple events */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ + OS_EventTaskWaitMulti(pevents_pend); /* Suspend task until events or timeout occurs */ + + OS_EXIT_CRITICAL(); + OS_Sched(); /* Find next highest priority task ready */ + OS_ENTER_CRITICAL(); + + switch (OSTCBCur->OSTCBStatPend) { /* Handle event posted, aborted, or timed-out */ + case OS_STAT_PEND_OK: + case OS_STAT_PEND_ABORT: + pevent = OSTCBCur->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { /* If task event ptr != NULL, ... */ + *pevents_rdy++ = pevent; /* ... return available event ... */ + *pevents_rdy = (OS_EVENT *)0; /* ... & NULL terminate return event array */ + events_rdy_nbr++; + + } else { /* Else NO event available, handle as timeout */ + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_TO; + OS_EventTaskRemoveMulti(OSTCBCur, pevents_pend); + } + break; + + case OS_STAT_PEND_TO: /* If events timed out, ... */ + default: /* ... remove task from events' wait lists */ + OS_EventTaskRemoveMulti(OSTCBCur, pevents_pend); + break; + } + + switch (OSTCBCur->OSTCBStatPend) { + case OS_STAT_PEND_OK: + switch (pevent->OSEventType) { /* Return event's message */ +#if (OS_SEM_EN > 0u) + case OS_EVENT_TYPE_SEM: + *pmsgs_rdy++ = (void *)0; /* NO message returned for semaphores */ + break; +#endif + +#if ((OS_MBOX_EN > 0u) || \ + ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))) + case OS_EVENT_TYPE_MBOX: + case OS_EVENT_TYPE_Q: + *pmsgs_rdy++ = (void *)OSTCBCur->OSTCBMsg; /* Return received message */ + break; +#endif + + case OS_EVENT_TYPE_MUTEX: + case OS_EVENT_TYPE_FLAG: + default: + OS_EXIT_CRITICAL(); + *pevents_rdy = (OS_EVENT *)0; /* NULL terminate return event array */ + *perr = OS_ERR_EVENT_TYPE; + return (events_rdy_nbr); + } + *perr = OS_ERR_NONE; + break; + + case OS_STAT_PEND_ABORT: + *pmsgs_rdy++ = (void *)0; /* NO message returned for abort */ + *perr = OS_ERR_PEND_ABORT; /* Indicate that event aborted */ + break; + + case OS_STAT_PEND_TO: + default: + *pmsgs_rdy++ = (void *)0; /* NO message returned for timeout */ + *perr = OS_ERR_TIMEOUT; /* Indicate that events timed out */ + 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 */ + OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; +#if ((OS_MBOX_EN > 0u) || \ + ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))) + OSTCBCur->OSTCBMsg = (void *)0; /* Clear task message */ +#endif + OS_EXIT_CRITICAL(); + + return (events_rdy_nbr); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* +* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to +* creating any uC/OS-II object and, prior to calling OSStart(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSInit (void) +{ + OSInitHookBegin(); /* Call port specific initialization code */ + + OS_InitMisc(); /* Initialize miscellaneous variables */ + + OS_InitRdyList(); /* Initialize the Ready List */ + + OS_InitTCBList(); /* Initialize the free list of OS_TCBs */ + + OS_InitEventList(); /* Initialize the free list of OS_EVENTs */ + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) + OS_FlagInit(); /* Initialize the event flag structures */ +#endif + +#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) + OS_MemInit(); /* Initialize the memory manager */ +#endif + +#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u) + OS_QInit(); /* Initialize the message queue structures */ +#endif + + OS_InitTaskIdle(); /* Create the Idle Task */ +#if OS_TASK_STAT_EN > 0u + OS_InitTaskStat(); /* Create the Statistic Task */ +#endif + +#if OS_TMR_EN > 0u + OSTmr_Init(); /* Initialize the Timer Manager */ +#endif + + OSInitHookEnd(); /* Call port specific init. code */ + +#if OS_DEBUG_EN > 0u + OSDebugInit(); +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* ENTER ISR +* +* Description: This function is used to notify uC/OS-II that you are about to service an interrupt +* service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus +* only perform rescheduling at the last nested ISR. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function should be called ith interrupts already disabled +* 2) Your ISR can directly increment OSIntNesting without calling this function because +* OSIntNesting has been declared 'global'. +* 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly. +* 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 5) You are allowed to nest interrupts up to 255 levels deep. +* 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because +* OSIntEnter() is always called with interrupts disabled. +********************************************************************************************************* +*/ + +void OSIntEnter (void) +{ + if (OSRunning == OS_TRUE) { + if (OSIntNesting < 255u) { + OSIntNesting++; /* Increment ISR nesting level */ + } + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* EXIT ISR +* +* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When +* the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether +* a new, high-priority task, is ready to run. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call +* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the +* end of the ISR. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OSIntExit (void) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + if (OSRunning == OS_TRUE) { + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0u) { /* Prevent OSIntNesting from wrapping */ + OSIntNesting--; + } + if (OSIntNesting == 0u) { /* Reschedule only if all ISRs complete ... */ + if (OSLockNesting == 0u) { /* ... and not locked. */ + OS_SchedNew(); + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ +#if OS_TASK_PROFILE_EN > 0u + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Keep track of the number of ctx switches */ + OSIntCtxSw(); /* Perform interrupt level ctx switch */ + } + } + } + OS_EXIT_CRITICAL(); + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INDICATE THAT IT'S NO LONGER SAFE TO CREATE OBJECTS +* +* Description: This function is called by the application code to indicate that all initialization has +* been completed and that kernel objects are no longer allowed to be created. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) You should call this function when you no longer want to allow application code to +* create kernel objects. +* 2) You need to define the macro 'OS_SAFETY_CRITICAL_IEC61508' +********************************************************************************************************* +*/ + +#ifdef OS_SAFETY_CRITICAL_IEC61508 +void OSSafetyCriticalStart (void) +{ + OSSafetyCriticalStartFlag = OS_TRUE; +} + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* PREVENT SCHEDULING +* +* Description: This function is used to prevent rescheduling to take place. This allows your application +* to prevent context switches until you are ready to permit context switching. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0u +void OSSchedLock (void) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0u) { /* Can't call from an ISR */ + if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */ + OSLockNesting++; /* Increment lock nesting level */ + } + } + OS_EXIT_CRITICAL(); + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ENABLE SCHEDULING +* +* Description: This function is used to re-allow rescheduling. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every +* call to OSSchedLock() you MUST have a call to OSSchedUnlock(). +********************************************************************************************************* +*/ + +#if OS_SCHED_LOCK_EN > 0u +void OSSchedUnlock (void) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + if (OSRunning == OS_TRUE) { /* Make sure multitasking is running */ + OS_ENTER_CRITICAL(); + if (OSLockNesting > 0u) { /* Do not decrement if already 0 */ + OSLockNesting--; /* Decrement lock nesting level */ + if (OSLockNesting == 0u) { /* See if scheduler is enabled and ... */ + if (OSIntNesting == 0u) { /* ... not in an ISR */ + OS_EXIT_CRITICAL(); + OS_Sched(); /* See if a HPT is ready */ + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } else { + OS_EXIT_CRITICAL(); + } + } +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* START MULTITASKING +* +* Description: This function is used to start the multitasking process which lets uC/OS-II manages the +* task that you have created. Before you can call OSStart(), you MUST have called OSInit() +* and you MUST have created at least one task. +* +* Arguments : none +* +* Returns : none +* +* Note : OSStartHighRdy() MUST: +* a) Call OSTaskSwHook() then, +* b) Set OSRunning to OS_TRUE. +* c) Load the context of the task pointed to by OSTCBHighRdy. +* d_ Execute the task. +********************************************************************************************************* +*/ + +void OSStart (void) +{ + if (OSRunning == OS_FALSE) { + OS_SchedNew(); /* Find highest priority's task priority number */ + OSPrioCur = OSPrioHighRdy; + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */ + OSTCBCur = OSTCBHighRdy; + OSStartHighRdy(); /* Execute target specific code to start task */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS INITIALIZATION +* +* Description: This function is called by your application to establish CPU usage by first determining +* how high a 32-bit counter would count to in 1 second if no other tasks were to execute +* during that time. CPU usage is then determined by a low priority task which keeps track +* of this 32-bit counter every second but this time, with other tasks running. CPU usage is +* determined by: +* +* OSIdleCtr +* CPU Usage (%) = 100 * (1 - ------------) +* OSIdleCtrMax +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0u +void OSStatInit (void) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + OSTimeDly(2u); /* Synchronize with clock tick */ + OS_ENTER_CRITICAL(); + OSIdleCtr = 0uL; /* Clear idle counter */ + OS_EXIT_CRITICAL(); + OSTimeDly(OS_TICKS_PER_SEC / 10u); /* Determine MAX. idle counter value for 1/10 second */ + OS_ENTER_CRITICAL(); + OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1/10 second */ + OSStatRdy = OS_TRUE; + OS_EXIT_CRITICAL(); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* PROCESS SYSTEM TICK +* +* Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known +* as a 'clock tick'). This function should be called by the ticker ISR but, can also be +* called by a high priority task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +void OSTimeTick (void) +{ + OS_TCB *ptcb; +#if OS_TICK_STEP_EN > 0u + BOOLEAN step; +#endif +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + +#if OS_TIME_TICK_HOOK_EN > 0u + OSTimeTickHook(); /* Call user definable hook */ +#endif +#if OS_TIME_GET_SET_EN > 0u + OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */ + OSTime++; + OS_EXIT_CRITICAL(); +#endif + if (OSRunning == OS_TRUE) { +#if OS_TICK_STEP_EN > 0u + switch (OSTickStepState) { /* Determine whether we need to process a tick */ + case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */ + step = OS_TRUE; + break; + + case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */ + step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */ + break; + + case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */ + step = OS_TRUE; /* ... step command from uC/OS-View */ + OSTickStepState = OS_TICK_STEP_WAIT; + break; + + default: /* Invalid case, correct situation */ + step = OS_TRUE; + OSTickStepState = OS_TICK_STEP_DIS; + break; + } + if (step == OS_FALSE) { /* Return if waiting for step command */ + return; + } +#endif + ptcb = OSTCBList; /* Point at first TCB in TCB list */ + while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */ + OS_ENTER_CRITICAL(); + if (ptcb->OSTCBDly != 0u) { /* No, Delayed or waiting for event with TO */ + ptcb->OSTCBDly--; /* Decrement nbr of ticks to end of delay */ + if (ptcb->OSTCBDly == 0u) { /* Check for timeout */ + + if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { + ptcb->OSTCBStat &= (INT8U)~(INT8U)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; + } + } + } + ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */ + OS_EXIT_CRITICAL(); + } + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* GET VERSION +* +* Description: This function is used to return the version number of uC/OS-II. The returned value +* corresponds to uC/OS-II's version number multiplied by 100. In other words, version 2.00 +* would be returned as 200. +* +* Arguments : none +* +* Returns : the version number of uC/OS-II multiplied by 100. +********************************************************************************************************* +*/ + +INT16U OSVersion (void) +{ + return (OS_VERSION); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DUMMY FUNCTION +* +* Description: This function doesn't do anything. It is called by OSTaskDel(). +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0u +void OS_Dummy (void) +{ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY TO RUN BASED ON EVENT OCCURING +* +* Description: This function is called by other uC/OS-II services and is used to ready a task that was +* waiting for an event to occur. +* +* Arguments : pevent is a pointer to the event control block corresponding to the event. +* +* pmsg is a pointer to a message. This pointer is used by message oriented services +* such as MAILBOXEs and QUEUEs. The pointer is not used when called by other +* service functions. +* +* msk is a mask that is used to clear the status byte of the TCB. For example, +* OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc. +* +* pend_stat is used to indicate the readied task's pending status: +* +* OS_STAT_PEND_OK Task ready due to a post (or delete), not a timeout or +* an abort. +* OS_STAT_PEND_ABORT Task ready due to an abort. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if (OS_EVENT_EN) +INT8U OS_EventTaskRdy (OS_EVENT *pevent, + void *pmsg, + INT8U msk, + INT8U pend_stat) +{ + OS_TCB *ptcb; + INT8U y; + INT8U x; + INT8U prio; +#if OS_LOWEST_PRIO > 63u + OS_PRIO *ptbl; +#endif + + +#if OS_LOWEST_PRIO <= 63u + y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message */ + x = OSUnMapTbl[pevent->OSEventTbl[y]]; + prio = (INT8U)((y << 3u) + x); /* Find priority of task getting the msg */ +#else + if ((pevent->OSEventGrp & 0xFFu) != 0u) { /* Find HPT waiting for message */ + y = OSUnMapTbl[ pevent->OSEventGrp & 0xFFu]; + } else { + y = OSUnMapTbl[(OS_PRIO)(pevent->OSEventGrp >> 8u) & 0xFFu] + 8u; + } + ptbl = &pevent->OSEventTbl[y]; + if ((*ptbl & 0xFFu) != 0u) { + x = OSUnMapTbl[*ptbl & 0xFFu]; + } else { + x = OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u; + } + prio = (INT8U)((y << 4u) + x); /* Find priority of task getting the msg */ +#endif + + ptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB */ + ptcb->OSTCBDly = 0u; /* Prevent OSTimeTick() from readying task */ +#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) + ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task */ +#else + pmsg = pmsg; /* Prevent compiler warning if not used */ +#endif + ptcb->OSTCBStat &= (INT8U)~msk; /* Clear bit associated with event type */ + ptcb->OSTCBStatPend = pend_stat; /* Set pend status of post or abort */ + /* See if task is ready (could be susp'd) */ + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { + OSRdyGrp |= ptcb->OSTCBBitY; /* Put task in the ready to run list */ + OSRdyTbl[y] |= ptcb->OSTCBBitX; + } + + OS_EventTaskRemove(ptcb, pevent); /* Remove this task from event wait list */ +#if (OS_EVENT_MULTI_EN > 0u) + if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { /* Remove this task from events' wait lists */ + OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr); + ptcb->OSTCBEventPtr = (OS_EVENT *)pevent;/* Return event as first multi-pend event ready*/ + } +#endif + + return (prio); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK WAIT FOR EVENT TO OCCUR +* +* Description: This function is called by other uC/OS-II services to suspend a task because an event has +* not occurred. +* +* Arguments : pevent is a pointer to the event control block for which the task will be waiting for. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if (OS_EVENT_EN) +void OS_EventTaskWait (OS_EVENT *pevent) +{ + INT8U y; + + + OSTCBCur->OSTCBEventPtr = pevent; /* Store ptr to ECB in TCB */ + + pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list */ + pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; + + y = OSTCBCur->OSTCBY; /* Task no longer ready */ + OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0u) { /* Clear event grp bit if this was only task pending */ + OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK WAIT FOR ANY OF MULTIPLE EVENTS TO OCCUR +* +* Description: This function is called by other uC/OS-II services to suspend a task because any one of +* multiple events has not occurred. +* +* Arguments : pevents_wait is a pointer to an array of event control blocks, NULL-terminated, for +* which the task will be waiting for. +* +* Returns : none. +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)) +void OS_EventTaskWaitMulti (OS_EVENT **pevents_wait) +{ + OS_EVENT **pevents; + OS_EVENT *pevent; + INT8U y; + + + OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; + OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)pevents_wait; /* Store ptr to ECBs in TCB */ + + pevents = pevents_wait; + pevent = *pevents; + while (pevent != (OS_EVENT *)0) { /* Put task in waiting lists */ + pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; + pevent->OSEventGrp |= OSTCBCur->OSTCBBitY; + pevents++; + pevent = *pevents; + } + + y = OSTCBCur->OSTCBY; /* Task no longer ready */ + OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0u) { /* Clear event grp bit if this was only task pending */ + OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* REMOVE TASK FROM EVENT WAIT LIST +* +* Description: Remove a task from an event's wait list. +* +* Arguments : ptcb is a pointer to the task to remove. +* +* pevent is a pointer to the event control block. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if (OS_EVENT_EN) +void OS_EventTaskRemove (OS_TCB *ptcb, + OS_EVENT *pevent) +{ + INT8U y; + + + y = ptcb->OSTCBY; + pevent->OSEventTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Remove task from wait list */ + if (pevent->OSEventTbl[y] == 0u) { + pevent->OSEventGrp &= (OS_PRIO)~ptcb->OSTCBBitY; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* REMOVE TASK FROM MULTIPLE EVENTS WAIT LISTS +* +* Description: Remove a task from multiple events' wait lists. +* +* Arguments : ptcb is a pointer to the task to remove. +* +* pevents_multi is a pointer to the array of event control blocks, NULL-terminated. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)) +void OS_EventTaskRemoveMulti (OS_TCB *ptcb, + OS_EVENT **pevents_multi) +{ + OS_EVENT **pevents; + OS_EVENT *pevent; + INT8U y; + OS_PRIO bity; + OS_PRIO bitx; + + + y = ptcb->OSTCBY; + bity = ptcb->OSTCBBitY; + bitx = ptcb->OSTCBBitX; + pevents = pevents_multi; + pevent = *pevents; + while (pevent != (OS_EVENT *)0) { /* Remove task from all events' wait lists */ + pevent->OSEventTbl[y] &= (OS_PRIO)~bitx; + if (pevent->OSEventTbl[y] == 0u) { + pevent->OSEventGrp &= (OS_PRIO)~bity; + } + pevents++; + pevent = *pevents; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST +* +* Description: This function is called by other uC/OS-II services to initialize the event wait list. +* +* Arguments : pevent is a pointer to the event control block allocated to the event. +* +* Returns : none +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ +#if (OS_EVENT_EN) +void OS_EventWaitListInit (OS_EVENT *pevent) +{ + INT8U i; + + + pevent->OSEventGrp = 0u; /* No task waiting on event */ + for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) { + pevent->OSEventTbl[i] = 0u; + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF EVENT CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of event control blocks. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitEventList (void) +{ +#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u) +#if (OS_MAX_EVENTS > 1u) + INT16U ix; + INT16U ix_next; + OS_EVENT *pevent1; + OS_EVENT *pevent2; + + + OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table */ + for (ix = 0u; ix < (OS_MAX_EVENTS - 1u); ix++) { /* Init. list of free EVENT control blocks */ + ix_next = ix + 1u; + pevent1 = &OSEventTbl[ix]; + pevent2 = &OSEventTbl[ix_next]; + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = pevent2; +#if OS_EVENT_NAME_EN > 0u + pevent1->OSEventName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + } + pevent1 = &OSEventTbl[ix]; + pevent1->OSEventType = OS_EVENT_TYPE_UNUSED; + pevent1->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_EN > 0u + pevent1->OSEventName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + OSEventFreeList = &OSEventTbl[0]; +#else + OSEventFreeList = &OSEventTbl[0]; /* Only have ONE event control block */ + OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED; + OSEventFreeList->OSEventPtr = (OS_EVENT *)0; +#if OS_EVENT_NAME_EN > 0u + OSEventFreeList->OSEventName = (INT8U *)"?"; /* Unknown name */ +#endif +#endif +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE MISCELLANEOUS VARIABLES +* +* Description: This function is called by OSInit() to initialize miscellaneous variables. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitMisc (void) +{ +#if OS_TIME_GET_SET_EN > 0u + OSTime = 0uL; /* Clear the 32-bit system clock */ +#endif + + OSIntNesting = 0u; /* Clear the interrupt nesting counter */ + OSLockNesting = 0u; /* Clear the scheduling lock counter */ + + OSTaskCtr = 0u; /* Clear the number of tasks */ + + OSRunning = OS_FALSE; /* Indicate that multitasking not started */ + + OSCtxSwCtr = 0u; /* Clear the context switch counter */ + OSIdleCtr = 0uL; /* Clear the 32-bit idle counter */ + +#if OS_TASK_STAT_EN > 0u + OSIdleCtrRun = 0uL; + OSIdleCtrMax = 0uL; + OSStatRdy = OS_FALSE; /* Statistic task is not ready */ +#endif + +#ifdef OS_SAFETY_CRITICAL_IEC61508 + OSSafetyCriticalStartFlag = OS_FALSE; /* Still allow creation of objects */ +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE READY LIST +* +* Description: This function is called by OSInit() to initialize the Ready List. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitRdyList (void) +{ + INT8U i; + + + OSRdyGrp = 0u; /* Clear the ready list */ + for (i = 0u; i < OS_RDY_TBL_SIZE; i++) { + OSRdyTbl[i] = 0u; + } + + OSPrioCur = 0u; + OSPrioHighRdy = 0u; + + OSTCBHighRdy = (OS_TCB *)0; + OSTCBCur = (OS_TCB *)0; +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE IDLE TASK +* +* Description: This function creates the Idle Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTaskIdle (void) +{ +#if OS_TASK_NAME_EN > 0u + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0u + #if OS_STK_GROWTH == 1u + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OS_TaskIdle, + (void *)0, /* No arguments passed to OS_TaskIdle() */ + &OSTaskIdleStk[0], /* Set Top-Of-Stack */ + OS_TASK_IDLE_PRIO, /* Lowest priority level */ + OS_TASK_IDLE_ID, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Bottom-Of-Stack */ + OS_TASK_IDLE_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1u + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u], + OS_TASK_IDLE_PRIO); + #else + (void)OSTaskCreate(OS_TaskIdle, + (void *)0, + &OSTaskIdleStk[0], + OS_TASK_IDLE_PRIO); + #endif +#endif + +#if OS_TASK_NAME_EN > 0u + OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)(void *)"uC/OS-II Idle", &err); +#endif +} +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* CREATING THE STATISTIC TASK +* +* Description: This function creates the Statistic Task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0u +static void OS_InitTaskStat (void) +{ +#if OS_TASK_NAME_EN > 0u + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0u + #if OS_STK_GROWTH == 1u + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #else + (void)OSTaskCreateExt(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO, /* One higher than the idle task */ + OS_TASK_STAT_ID, + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Bottom-Of-Stack */ + OS_TASK_STAT_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */ + #endif +#else + #if OS_STK_GROWTH == 1u + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #else + (void)OSTaskCreate(OS_TaskStat, + (void *)0, /* No args passed to OS_TaskStat()*/ + &OSTaskStatStk[0], /* Set Top-Of-Stack */ + OS_TASK_STAT_PRIO); /* One higher than the idle task */ + #endif +#endif + +#if OS_TASK_NAME_EN > 0u + OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)(void *)"uC/OS-II Stat", &err); +#endif +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TASK CONTROL BLOCKS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TCBs. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +static void OS_InitTCBList (void) +{ + INT8U ix; + INT8U ix_next; + OS_TCB *ptcb1; + OS_TCB *ptcb2; + + + OS_MemClr((INT8U *)&OSTCBTbl[0], sizeof(OSTCBTbl)); /* Clear all the TCBs */ + OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl)); /* Clear the priority table */ + for (ix = 0u; ix < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1u); ix++) { /* Init. list of free TCBs */ + ix_next = ix + 1u; + ptcb1 = &OSTCBTbl[ix]; + ptcb2 = &OSTCBTbl[ix_next]; + ptcb1->OSTCBNext = ptcb2; +#if OS_TASK_NAME_EN > 0u + ptcb1->OSTCBTaskName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + } + ptcb1 = &OSTCBTbl[ix]; + ptcb1->OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */ +#if OS_TASK_NAME_EN > 0u + ptcb1->OSTCBTaskName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + OSTCBList = (OS_TCB *)0; /* TCB lists initializations */ + OSTCBFreeList = &OSTCBTbl[0]; +} +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR A SECTION OF MEMORY +* +* Description: This function is called by other uC/OS-II services to clear a contiguous block of RAM. +* +* Arguments : pdest is the start of the RAM to clear (i.e. write 0x00 to) +* +* size is the number of bytes to clear. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Note that we can only clear up to 64K bytes of RAM. This is not an issue because none +* of the uses of this function gets close to this limit. +* 3) The clear is done one byte at a time since this will work on any processor irrespective +* of the alignment of the destination. +********************************************************************************************************* +*/ + +void OS_MemClr (INT8U *pdest, + INT16U size) +{ + while (size > 0u) { + *pdest++ = (INT8U)0; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* COPY A BLOCK OF MEMORY +* +* Description: This function is called by other uC/OS-II services to copy a block of memory from one +* location to another. +* +* Arguments : pdest is a pointer to the 'destination' memory block +* +* psrc is a pointer to the 'source' memory block +* +* size is the number of bytes to copy. +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. There is +* no provision to handle overlapping memory copy. However, that's not a problem since this +* is not a situation that will happen. +* 2) Note that we can only copy up to 64K bytes of RAM +* 3) The copy is done one byte at a time since this will work on any processor irrespective +* of the alignment of the source and destination. +********************************************************************************************************* +*/ + +void OS_MemCopy (INT8U *pdest, + INT8U *psrc, + INT16U size) +{ + while (size > 0u) { + *pdest++ = *psrc++; + size--; + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* SCHEDULER +* +* Description: This function is called by other uC/OS-II services to determine whether a new, high +* priority task has been made ready to run. This function is invoked by TASK level code +* and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling). +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock()) +********************************************************************************************************* +*/ + +void OS_Sched (void) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + OS_ENTER_CRITICAL(); + if (OSIntNesting == 0u) { /* Schedule only if all ISRs done and ... */ + if (OSLockNesting == 0u) { /* ... scheduler is not locked */ + OS_SchedNew(); + OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; + if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ +#if OS_TASK_PROFILE_EN > 0u + OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */ +#endif + OSCtxSwCtr++; /* Increment context switch counter */ + OS_TASK_SW(); /* Perform a context switch */ + } + } + } + OS_EXIT_CRITICAL(); +} + + +/* +********************************************************************************************************* +* FIND HIGHEST PRIORITY TASK READY TO RUN +* +* Description: This function is called by other uC/OS-II services to determine the highest priority task +* that is ready to run. The global variable 'OSPrioHighRdy' is changed accordingly. +* +* Arguments : none +* +* Returns : none +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) Interrupts are assumed to be disabled when this function is called. +********************************************************************************************************* +*/ + +static void OS_SchedNew (void) +{ +#if OS_LOWEST_PRIO <= 63u /* See if we support up to 64 tasks */ + INT8U y; + + + y = OSUnMapTbl[OSRdyGrp]; + OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]); +#else /* We support up to 256 tasks */ + INT8U y; + OS_PRIO *ptbl; + + + if ((OSRdyGrp & 0xFFu) != 0u) { + y = OSUnMapTbl[OSRdyGrp & 0xFFu]; + } else { + y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u; + } + ptbl = &OSRdyTbl[y]; + if ((*ptbl & 0xFFu) != 0u) { + OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]); + } else { + OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u); + } +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DETERMINE THE LENGTH OF AN ASCII STRING +* +* Description: This function is called by other uC/OS-II services to determine the size of an ASCII string +* (excluding the NUL character). +* +* Arguments : psrc is a pointer to the string for which we need to know the size. +* +* Returns : The size of the string (excluding the NUL terminating character) +* +* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it. +* 2) The string to check must be less than 255 characters long. +********************************************************************************************************* +*/ + +#if (OS_EVENT_NAME_EN > 0u) || (OS_FLAG_NAME_EN > 0u) || (OS_MEM_NAME_EN > 0u) || (OS_TASK_NAME_EN > 0u) || (OS_TMR_CFG_NAME_EN > 0u) +INT8U OS_StrLen (INT8U *psrc) +{ + INT8U len; + + + len = 0u; + while (*psrc != OS_ASCII_NUL) { + psrc++; + len++; + } + return (len); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* IDLE TASK +* +* Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks +* executes because they are ALL waiting for event(s) to occur. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be +* enabled for at least a few instructions. On some processors (ex. Philips XA), enabling +* and then disabling interrupts didn't allow the processor enough time to have interrupts +* enabled before they were disabled again. uC/OS-II would thus never recognize +* interrupts. +* 2) This hook has been added to allow you to do such things as STOP the CPU to conserve +* power. +********************************************************************************************************* +*/ + +void OS_TaskIdle (void *p_arg) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */ + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtr++; + OS_EXIT_CRITICAL(); + OSTaskIdleHook(); /* Call user definable HOOK */ + } +} +/*$PAGE*/ +/* +********************************************************************************************************* +* STATISTICS TASK +* +* Description: This task is internal to uC/OS-II and is used to compute some statistics about the +* multitasking environment. Specifically, OS_TaskStat() computes the CPU usage. +* CPU usage is determined by: +* +* OSIdleCtr +* OSCPUUsage = 100 * (1 - ------------) (units are in %) +* OSIdleCtrMax +* +* Arguments : parg this pointer is not used at this time. +* +* Returns : none +* +* Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the +* next higher priority, OS_TASK_IDLE_PRIO-1. +* 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0. +* 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the +* maximum value for the idle counter. +********************************************************************************************************* +*/ + +#if OS_TASK_STAT_EN > 0u +void OS_TaskStat (void *p_arg) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */ + while (OSStatRdy == OS_FALSE) { + OSTimeDly(2u * OS_TICKS_PER_SEC / 10u); /* Wait until statistic task is ready */ + } + OSIdleCtrMax /= 100uL; + if (OSIdleCtrMax == 0uL) { + OSCPUUsage = 0u; +#if OS_TASK_SUSPEND_EN > 0u + (void)OSTaskSuspend(OS_PRIO_SELF); +#else + for (;;) { + OSTimeDly(OS_TICKS_PER_SEC); + } +#endif + } + for (;;) { + OS_ENTER_CRITICAL(); + OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */ + OSIdleCtr = 0uL; /* Reset the idle counter for the next second */ + OS_EXIT_CRITICAL(); + OSCPUUsage = (INT8U)(100uL - OSIdleCtrRun / OSIdleCtrMax); + OSTaskStatHook(); /* Invoke user definable hook */ +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) + OS_TaskStatStkChk(); /* Check the stacks for each task */ +#endif + OSTimeDly(OS_TICKS_PER_SEC / 10u); /* Accumulate OSIdleCtr for the next 1/10 second */ + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK ALL TASK STACKS +* +* Description: This function is called by OS_TaskStat() to check the stacks of each active task. +* +* Arguments : none +* +* Returns : none +********************************************************************************************************* +*/ + +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +void OS_TaskStatStkChk (void) +{ + OS_TCB *ptcb; + OS_STK_DATA stk_data; + INT8U err; + INT8U prio; + + + for (prio = 0u; prio <= OS_TASK_IDLE_PRIO; prio++) { + err = OSTaskStkChk(prio, &stk_data); + if (err == OS_ERR_NONE) { + ptcb = OSTCBPrioTbl[prio]; + if (ptcb != (OS_TCB *)0) { /* Make sure task 'ptcb' is ... */ + if (ptcb != OS_TCB_RESERVED) { /* ... still valid. */ +#if OS_TASK_PROFILE_EN > 0u + #if OS_STK_GROWTH == 1u + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom + ptcb->OSTCBStkSize; + #else + ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom - ptcb->OSTCBStkSize; + #endif + ptcb->OSTCBStkUsed = stk_data.OSUsed; /* Store the number of bytes used */ +#endif + } + } + } + } +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE TCB +* +* Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when +* a task is created (see OSTaskCreate() and OSTaskCreateExt()). +* +* Arguments : prio is the priority of the task being created +* +* ptos is a pointer to the task's top-of-stack assuming that the CPU registers +* have been placed on the stack. Note that the top-of-stack corresponds to a +* 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory +* location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU +* specific. +* +* pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by +* 'OSTaskCreate()'. +* +* id is the task's ID (0..65535) +* +* stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us +* then, 'stk_size' contains the number of bytes for the stack. If the stack +* units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack +* units are established by the #define constant OS_STK which is CPU +* specific. 'stk_size' is 0 if called by 'OSTaskCreate()'. +* +* pext is a pointer to a user supplied memory area that is used to extend the task +* control block. This allows you to store the contents of floating-point +* registers, MMU registers or anything else you could find useful during a +* context switch. You can even assign a name to each task and store this name +* in this TCB extension. A NULL pointer is passed if called by OSTaskCreate(). +* +* opt options as passed to 'OSTaskCreateExt()' or, +* 0 if called from 'OSTaskCreate()'. +* +* Returns : OS_ERR_NONE if the call was successful +* OS_ERR_TASK_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot +* be created. +* +* Note : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +INT8U OS_TCBInit (INT8U prio, + OS_STK *ptos, + OS_STK *pbos, + INT16U id, + INT32U stk_size, + void *pext, + INT16U opt) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif +#if OS_TASK_REG_TBL_SIZE > 0u + INT8U i; +#endif + + + OS_ENTER_CRITICAL(); + ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */ + if (ptcb != (OS_TCB *)0) { + OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */ + OS_EXIT_CRITICAL(); + ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */ + ptcb->OSTCBPrio = prio; /* Load task priority into TCB */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ + ptcb->OSTCBDly = 0u; /* Task is not delayed */ + +#if OS_TASK_CREATE_EXT_EN > 0u + ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */ + ptcb->OSTCBStkSize = stk_size; /* Store stack size */ + ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */ + ptcb->OSTCBOpt = opt; /* Store task options */ + ptcb->OSTCBId = id; /* Store task ID */ +#else + pext = pext; /* Prevent compiler warning if not used */ + stk_size = stk_size; + pbos = pbos; + opt = opt; + id = id; +#endif + +#if OS_TASK_DEL_EN > 0u + ptcb->OSTCBDelReq = OS_ERR_NONE; +#endif + +#if OS_LOWEST_PRIO <= 63u /* Pre-compute X, Y */ + ptcb->OSTCBY = (INT8U)(prio >> 3u); + ptcb->OSTCBX = (INT8U)(prio & 0x07u); +#else /* Pre-compute X, Y */ + ptcb->OSTCBY = (INT8U)((INT8U)(prio >> 4u) & 0xFFu); + ptcb->OSTCBX = (INT8U) (prio & 0x0Fu); +#endif + /* Pre-compute BitX and BitY */ + ptcb->OSTCBBitY = (OS_PRIO)(1uL << ptcb->OSTCBY); + ptcb->OSTCBBitX = (OS_PRIO)(1uL << ptcb->OSTCBX); + +#if (OS_EVENT_EN) + ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */ +#if (OS_EVENT_MULTI_EN > 0u) + ptcb->OSTCBEventMultiPtr = (OS_EVENT **)0; /* Task is not pending on any events */ +#endif +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) && (OS_TASK_DEL_EN > 0u) + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; /* Task is not pending on an event flag */ +#endif + +#if (OS_MBOX_EN > 0u) || ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) + ptcb->OSTCBMsg = (void *)0; /* No message received */ +#endif + +#if OS_TASK_PROFILE_EN > 0u + ptcb->OSTCBCtxSwCtr = 0uL; /* Initialize profiling variables */ + ptcb->OSTCBCyclesStart = 0uL; + ptcb->OSTCBCyclesTot = 0uL; + ptcb->OSTCBStkBase = (OS_STK *)0; + ptcb->OSTCBStkUsed = 0uL; +#endif + +#if OS_TASK_NAME_EN > 0u + ptcb->OSTCBTaskName = (INT8U *)(void *)"?"; +#endif + +#if OS_TASK_REG_TBL_SIZE > 0u /* Initialize the task variables */ + for (i = 0u; i < OS_TASK_REG_TBL_SIZE; i++) { + ptcb->OSTCBRegTbl[i] = 0u; + } +#endif + + OSTCBInitHook(ptcb); + + OSTaskCreateHook(ptcb); /* Call user defined hook */ + + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = ptcb; + ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */ + ptcb->OSTCBPrev = (OS_TCB *)0; + if (OSTCBList != (OS_TCB *)0) { + OSTCBList->OSTCBPrev = ptcb; + } + OSTCBList = ptcb; + OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OSTaskCtr++; /* Increment the #tasks counter */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NO_MORE_TCB); +} + diff --git a/UCOS/CORE/os_flag.c b/UCOS/CORE/os_flag.c new file mode 100644 index 0000000..abd0d1e --- /dev/null +++ b/UCOS/CORE/os_flag.c @@ -0,0 +1,1215 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* EVENT FLAG MANAGEMENT +* +* (c) Copyright 1992-2009, Micrium, Weston, FL +* All Rights Reserved +* +* File : OS_FLAG.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 +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) +/* +********************************************************************************************************* +* LOCAL PROTOTYPES +********************************************************************************************************* +*/ + +static void OS_FlagBlock(OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT32U timeout); +static BOOLEAN OS_FlagTaskRdy(OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy); + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP +* +* Description: This function is called to check the status of a combination of bits to be set or cleared +* in an event flag group. Your application can check for ANY bit to be set/cleared or ALL +* bits to be set/cleared. +* +* This call does not block if the desired flags are not present. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE No error +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag +* group handle. +* OS_ERR_FLAG_NOT_RDY The desired flags you are waiting for are not +* available. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task or ISR +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +#if OS_FLAG_ACCEPT_EN > 0u +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT8U *perr) +{ + OS_FLAGS flags_rdy; + INT8U result; + BOOLEAN consume; +#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 (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= ~OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + *perr = OS_ERR_NONE; /* Assume NO error until proven otherwise. */ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /* Clear ONLY the flags we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /* Clear ONLY the flags we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + +#if OS_FLAG_WAIT_CLR_EN > 0u + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + } else { + *perr = OS_ERR_FLAG_NOT_RDY; + } + OS_EXIT_CRITICAL(); + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + break; + } + return (flags_rdy); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE AN EVENT FLAG +* +* Description: This function is called to create an event flag group. +* +* Arguments : flags Contains the initial value to store in the event flag group. +* +* 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 an Event Flag from an +* ISR. +* OS_ERR_FLAG_GRP_DEPLETED if there are no more event flag groups +* +* Returns : A pointer to an event flag group or a NULL pointer if no more groups are available. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, + INT8U *perr) +{ + OS_FLAG_GRP *pgrp; +#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 (OSIntNesting > 0u) { /* See if called from ISR ... */ + *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */ + return ((OS_FLAG_GRP *)0); + } + OS_ENTER_CRITICAL(); + pgrp = OSFlagFreeList; /* Get next free event flag */ + if (pgrp != (OS_FLAG_GRP *)0) { /* See if we have event flag groups available */ + /* Adjust free list */ + OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList; + pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* Set to event flag group type */ + pgrp->OSFlagFlags = flags; /* Set to desired initial value */ + pgrp->OSFlagWaitList = (void *)0; /* Clear list of tasks waiting on flags */ +#if OS_FLAG_NAME_EN > 0u + pgrp->OSFlagName = (INT8U *)(void *)"?"; +#endif + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_GRP_DEPLETED; + } + return (pgrp); /* Return pointer to event flag group */ +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE AN EVENT FLAG GROUP +* +* Description: This function deletes an event flag group and readies all tasks pending on the event flag +* group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* opt determines delete options as follows: +* opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending +* opt == OS_DEL_ALWAYS Deletes the event flag group 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 event flag group was +* deleted +* OS_ERR_DEL_ISR If you attempted to delete the event flag group from +* an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group +* OS_ERR_INVALID_OPT An invalid option was specified +* OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag +* group. +* +* Returns : pgrp upon error +* (OS_EVENT *)0 if the event flag group was successfully deleted. +* +* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of +* the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend(). +* 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 event flag group. +********************************************************************************************************* +*/ + +#if OS_FLAG_DEL_EN > 0u +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, + INT8U opt, + INT8U *perr) +{ + BOOLEAN tasks_waiting; + OS_FLAG_NODE *pnode; + OS_FLAG_GRP *pgrp_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 (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return (pgrp); + } +#endif + if (OSIntNesting > 0u) { /* See if called from ISR ... */ + *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ + return (pgrp); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event group type */ + *perr = OS_ERR_EVENT_TYPE; + return (pgrp); + } + OS_ENTER_CRITICAL(); + if (pgrp->OSFlagWaitList != (void *)0) { /* See if any tasks waiting on event flags */ + tasks_waiting = OS_TRUE; /* Yes */ + } else { + tasks_waiting = OS_FALSE; /* No */ + } + switch (opt) { + case OS_DEL_NO_PEND: /* Delete group if no task waiting */ + if (tasks_waiting == OS_FALSE) { +#if OS_FLAG_NAME_EN > 0u + pgrp->OSFlagName = (INT8U *)(void *)"?"; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + } else { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_TASK_WAITING; + pgrp_return = pgrp; + } + break; + + case OS_DEL_ALWAYS: /* Always delete the event flag group */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Ready ALL tasks waiting for flags */ + (void)OS_FlagTaskRdy(pnode, (OS_FLAGS)0); + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + } +#if OS_FLAG_NAME_EN > 0u + pgrp->OSFlagName = (INT8U *)(void *)"?"; +#endif + pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list */ + pgrp->OSFlagFlags = (OS_FLAGS)0; + OSFlagFreeList = pgrp; + 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; + pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */ + break; + + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_INVALID_OPT; + pgrp_return = pgrp; + break; + } + return (pgrp_return); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF AN EVENT FLAG GROUP +* +* Description: This function is used to obtain the name assigned to an event flag group +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is pointer to a pointer to an ASCII string that will receive the name of the event flag +* group. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_GET_ISR if you called this function from an ISR +* +* Returns : The length of the string or 0 if the 'pgrp' is a NULL pointer. +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_EN > 0u +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, + 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 (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + 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(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return (0u); + } + *pname = pgrp->OSFlagName; + len = OS_StrLen(*pname); + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO AN EVENT FLAG GROUP +* +* Description: This function assigns a name to an event flag group. +* +* Arguments : pgrp is a pointer to the event flag group. +* +* pname is a pointer to an ASCII string that will be used as the name of the event flag +* group. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp' +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ + +#if OS_FLAG_NAME_EN > 0u +void OSFlagNameSet (OS_FLAG_GRP *pgrp, + 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 (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + 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(); + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { + OS_EXIT_CRITICAL(); + *perr = OS_ERR_EVENT_TYPE; + return; + } + pgrp->OSFlagName = pname; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* WAIT ON AN EVENT FLAG GROUP +* +* Description: This function is called to wait for a combination of bits to be set in an event flag +* group. Your application can wait for ANY bit to be set or ALL bits to be set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set or ANY of the bits to be set. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will wait for ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will wait for ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_CLR_ANY You will wait for ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ANY You will wait for ANY bit in 'mask' to be set (1) +* +* NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by +* the call. Example, to wait for any flag in a group AND then clear +* the flags that are present, set 'wait_type' to: +* +* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME +* +* timeout is an optional timeout (in clock ticks) that your task will wait for the +* desired bit combination. If you specify 0, however, your task will wait +* forever at the specified event flag group or, until a message arrives. +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The desired bits have been set within the specified +* 'timeout'. +* OS_ERR_PEND_ISR If you tried to PEND from an ISR +* OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_TIMEOUT The bit(s) have not been set in the specified +* 'timeout'. +* OS_ERR_PEND_ABORT The wait on the flag was aborted. +* OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. +* +* Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error +* occurred. +* +* Called from: Task ONLY +* +* Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The +* function NOW returns the flags that were ready INSTEAD of the current state of the +* event flags. +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT32U timeout, + INT8U *perr) +{ + OS_FLAG_NODE node; + OS_FLAGS flags_rdy; + INT8U result; + INT8U pend_stat; + BOOLEAN consume; +#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 (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (OSIntNesting > 0u) { /* See if called from ISR ... */ + *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ + return ((OS_FLAGS)0); + } + if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ + *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ + return ((OS_FLAGS)0); + } + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + result = (INT8U)(wait_type & OS_FLAG_CONSUME); + if (result != (INT8U)0) { /* See if we need to consume the flags */ + wait_type &= (INT8U)~(INT8U)OS_FLAG_CONSUME; + consume = OS_TRUE; + } else { + consume = OS_FALSE; + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /* Clear ONLY the flags we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_SET_ANY: + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /* Clear ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0u + case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */ + if (flags_rdy == flags) { /* Must match ALL the bits that we want */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; + + case OS_FLAG_WAIT_CLR_ANY: + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */ + if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */ + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ + } + OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */ + OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */ + *perr = OS_ERR_NONE; + return (flags_rdy); + } else { /* Block task until events occur or timeout */ + OS_FlagBlock(pgrp, &node, flags, wait_type, timeout); + OS_EXIT_CRITICAL(); + } + break; +#endif + + default: + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + *perr = OS_ERR_FLAG_WAIT_TYPE; + return (flags_rdy); + } +/*$PAGE*/ + OS_Sched(); /* Find next HPT ready to run */ + OS_ENTER_CRITICAL(); + if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* Have we timed-out or aborted? */ + pend_stat = OSTCBCur->OSTCBStatPend; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OS_FlagUnlink(&node); + OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Yes, make task ready-to-run */ + OS_EXIT_CRITICAL(); + flags_rdy = (OS_FLAGS)0; + switch (pend_stat) { + case OS_STAT_PEND_ABORT: + *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted waiting */ + break; + + case OS_STAT_PEND_TO: + default: + *perr = OS_ERR_TIMEOUT; /* Indicate that we timed-out waiting */ + break; + } + return (flags_rdy); + } + flags_rdy = OSTCBCur->OSTCBFlagsRdy; + if (consume == OS_TRUE) { /* See if we need to consume the flags */ + switch (wait_type) { + case OS_FLAG_WAIT_SET_ALL: + case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */ + pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; + break; + +#if OS_FLAG_WAIT_CLR_EN > 0u + case OS_FLAG_WAIT_CLR_ALL: + case OS_FLAG_WAIT_CLR_ANY: /* Set ONLY the flags we got */ + pgrp->OSFlagFlags |= flags_rdy; + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + } + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; /* Event(s) must have occurred */ + return (flags_rdy); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* GET FLAGS WHO CAUSED TASK TO BECOME READY +* +* Description: This function is called to obtain the flags that caused the task to become ready to run. +* In other words, this function allows you to tell "Who done it!". +* +* Arguments : None +* +* Returns : The flags that caused the task to be ready. +* +* Called from: Task ONLY +********************************************************************************************************* +*/ + +OS_FLAGS OSFlagPendGetFlagsRdy (void) +{ + OS_FLAGS flags; +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + OS_ENTER_CRITICAL(); + flags = OSTCBCur->OSTCBFlagsRdy; + OS_EXIT_CRITICAL(); + return (flags); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* POST EVENT FLAG BIT(S) +* +* Description: This function is called to set or clear some bits in an event flag group. The bits to +* set or clear are specified by a 'bit mask'. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* flags If 'opt' (see below) is OS_FLAG_SET, each bit that is set in 'flags' will +* set the corresponding bit in the event flag group. e.g. to set bits 0, 4 +* and 5 you would set 'flags' to: +* +* 0x31 (note, bit 0 is least significant bit) +* +* If 'opt' (see below) is OS_FLAG_CLR, each bit that is set in 'flags' will +* CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0, +* 4 and 5 you would specify 'flags' as: +* +* 0x31 (note, bit 0 is least significant bit) +* +* opt indicates whether the flags will be: +* set (OS_FLAG_SET) or +* cleared (OS_FLAG_CLR) +* +* perr is a pointer to an error code and can be: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* OS_ERR_FLAG_INVALID_OPT You specified an invalid option +* +* Returns : the new value of the event flags bits that are still set. +* +* Called From: Task or ISR +* +* WARNING(s) : 1) The execution time of this function depends on the number of tasks waiting on the event +* flag group. +* 2) The amount of time interrupts are DISABLED depends on the number of tasks waiting on +* the event flag group. +********************************************************************************************************* +*/ +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U opt, + INT8U *perr) +{ + OS_FLAG_NODE *pnode; + BOOLEAN sched; + OS_FLAGS flags_cur; + OS_FLAGS flags_rdy; + BOOLEAN rdy; +#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 (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } +/*$PAGE*/ + OS_ENTER_CRITICAL(); + switch (opt) { + case OS_FLAG_CLR: + pgrp->OSFlagFlags &= (OS_FLAGS)~flags; /* Clear the flags specified in the group */ + break; + + case OS_FLAG_SET: + pgrp->OSFlagFlags |= flags; /* Set the flags specified in the group */ + break; + + default: + OS_EXIT_CRITICAL(); /* INVALID option */ + *perr = OS_ERR_FLAG_INVALID_OPT; + return ((OS_FLAGS)0); + } + sched = OS_FALSE; /* Indicate that we don't need rescheduling */ + pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + while (pnode != (OS_FLAG_NODE *)0) { /* Go through all tasks waiting on event flag(s) */ + switch (pnode->OSFlagNodeWaitType) { + case OS_FLAG_WAIT_SET_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_SET_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags); + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + +#if OS_FLAG_WAIT_CLR_EN > 0u + case OS_FLAG_WAIT_CLR_ALL: /* See if all req. flags are set for current node */ + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; + if (flags_rdy == pnode->OSFlagNodeFlags) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; + + case OS_FLAG_WAIT_CLR_ANY: /* See if any flag set */ + flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; + if (flags_rdy != (OS_FLAGS)0) { + rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */ + if (rdy == OS_TRUE) { + sched = OS_TRUE; /* When done we will reschedule */ + } + } + break; +#endif + default: + OS_EXIT_CRITICAL(); + *perr = OS_ERR_FLAG_WAIT_TYPE; + return ((OS_FLAGS)0); + } + pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */ + } + OS_EXIT_CRITICAL(); + if (sched == OS_TRUE) { + OS_Sched(); + } + OS_ENTER_CRITICAL(); + flags_cur = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags_cur); +} +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY EVENT FLAG +* +* Description: This function is used to check the value of the event flag group. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* perr is a pointer to an error code returned to the called: +* OS_ERR_NONE The call was successfull +* OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer +* OS_ERR_EVENT_TYPE You are not pointing to an event flag group +* +* Returns : The current value of the event flag group. +* +* Called From: Task or ISR +********************************************************************************************************* +*/ + +#if OS_FLAG_QUERY_EN > 0u +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, + INT8U *perr) +{ + OS_FLAGS flags; +#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 (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ + *perr = OS_ERR_FLAG_INVALID_PGRP; + return ((OS_FLAGS)0); + } +#endif + if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ + *perr = OS_ERR_EVENT_TYPE; + return ((OS_FLAGS)0); + } + OS_ENTER_CRITICAL(); + flags = pgrp->OSFlagFlags; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (flags); /* Return the current value of the event flags */ +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS +* +* Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired +* event flag bit(s) are set. +* +* Arguments : pgrp is a pointer to the desired event flag group. +* +* pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. +* The bits you want are specified by setting the corresponding bits in +* 'flags'. e.g. if your application wants to wait for bits 0 and 1 then +* 'flags' would contain 0x03. +* +* wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits +* to be set/cleared. +* You can specify the following argument: +* +* OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'mask' to be clear (0) +* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'mask' to be clear (0) +* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'mask' to be set (1) +* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'mask' to be set (1) +* +* timeout is the desired amount of time that the task will wait for the event flag +* bit(s) to be set. +* +* Returns : none +* +* Called by : OSFlagPend() OS_FLAG.C +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static void OS_FlagBlock (OS_FLAG_GRP *pgrp, + OS_FLAG_NODE *pnode, + OS_FLAGS flags, + INT8U wait_type, + INT32U timeout) +{ + OS_FLAG_NODE *pnode_next; + INT8U y; + + + OSTCBCur->OSTCBStat |= OS_STAT_FLAG; + OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; + OSTCBCur->OSTCBDly = timeout; /* Store timeout in task's TCB */ +#if OS_TASK_DEL_EN > 0u + OSTCBCur->OSTCBFlagNode = pnode; /* TCB to link to node */ +#endif + pnode->OSFlagNodeFlags = flags; /* Save the flags that we need to wait for */ + pnode->OSFlagNodeWaitType = wait_type; /* Save the type of wait we are doing */ + pnode->OSFlagNodeTCB = (void *)OSTCBCur; /* Link to task's TCB */ + pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */ + pnode->OSFlagNodePrev = (void *)0; + pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* Link to Event Flag Group */ + pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; + if (pnode_next != (void *)0) { /* Is this the first NODE to insert? */ + pnode_next->OSFlagNodePrev = pnode; /* No, link in doubly linked list */ + } + pgrp->OSFlagWaitList = (void *)pnode; + + y = OSTCBCur->OSTCBY; /* Suspend current task until flag(s) received */ + OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; + if (OSRdyTbl[y] == 0x00u) { + OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; + } +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* INITIALIZE THE EVENT FLAG MODULE +* +* Description: This function is called by uC/OS-II to initialize the event flag module. Your application +* MUST NOT call this function. In other words, this function is internal to uC/OS-II. +* +* Arguments : none +* +* Returns : none +* +* WARNING : You MUST NOT call this function from your code. This is an INTERNAL function to uC/OS-II. +********************************************************************************************************* +*/ + +void OS_FlagInit (void) +{ +#if OS_MAX_FLAGS == 1u + OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */ + OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED; + OSFlagFreeList->OSFlagWaitList = (void *)0; + OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0; +#if OS_FLAG_NAME_EN > 0u + OSFlagFreeList->OSFlagName = (INT8U *)"?"; +#endif +#endif + +#if OS_MAX_FLAGS >= 2u + INT16U ix; + INT16U ix_next; + OS_FLAG_GRP *pgrp1; + OS_FLAG_GRP *pgrp2; + + + OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); /* Clear the flag group table */ + for (ix = 0u; ix < (OS_MAX_FLAGS - 1u); ix++) { /* Init. list of free EVENT FLAGS */ + ix_next = ix + 1u; + pgrp1 = &OSFlagTbl[ix]; + pgrp2 = &OSFlagTbl[ix_next]; + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)pgrp2; +#if OS_FLAG_NAME_EN > 0u + pgrp1->OSFlagName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + } + pgrp1 = &OSFlagTbl[ix]; + pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; + pgrp1->OSFlagWaitList = (void *)0; +#if OS_FLAG_NAME_EN > 0u + pgrp1->OSFlagName = (INT8U *)(void *)"?"; /* Unknown name */ +#endif + OSFlagFreeList = &OSFlagTbl[0]; +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED +* +* Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the +* desired event flag bits have been set. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* flags_rdy contains the bit pattern of the event flags that cause the task to become +* ready-to-run. +* +* Returns : OS_TRUE If the task has been placed in the ready list and thus needs scheduling +* OS_FALSE The task is still not ready to run and thus scheduling is not necessary +* +* Called by : OSFlagsPost() OS_FLAG.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, + OS_FLAGS flags_rdy) +{ + OS_TCB *ptcb; + BOOLEAN sched; + + + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* Point to TCB of waiting task */ + ptcb->OSTCBDly = 0u; + ptcb->OSTCBFlagsRdy = flags_rdy; + ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_FLAG; + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Task now ready? */ + OSRdyGrp |= ptcb->OSTCBBitY; /* Put task into ready list */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + sched = OS_TRUE; + } else { + sched = OS_FALSE; + } + OS_FlagUnlink(pnode); + return (sched); +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* UNLINK EVENT FLAG NODE FROM WAITING LIST +* +* Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a +* list of tasks waiting for the event flag. +* +* Arguments : pnode is a pointer to a structure which contains data about the task waiting for +* event flag bit(s) to be set. +* +* Returns : none +* +* Called by : OS_FlagTaskRdy() OS_FLAG.C +* OSFlagPend() OS_FLAG.C +* OSTaskDel() OS_TASK.C +* +* Note(s) : 1) This function assumes that interrupts are disabled. +* 2) This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_FlagUnlink (OS_FLAG_NODE *pnode) +{ +#if OS_TASK_DEL_EN > 0u + OS_TCB *ptcb; +#endif + OS_FLAG_GRP *pgrp; + OS_FLAG_NODE *pnode_prev; + OS_FLAG_NODE *pnode_next; + + + pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev; + pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; + if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */ + pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp; + pgrp->OSFlagWaitList = (void *)pnode_next; /* Update list for new 1st node */ + if (pnode_next != (OS_FLAG_NODE *)0) { + pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* Link new 1st node PREV to NULL */ + } + } else { /* No, A node somewhere in the list */ + pnode_prev->OSFlagNodeNext = pnode_next; /* Link around the node to unlink */ + if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */ + pnode_next->OSFlagNodePrev = pnode_prev; /* No, Link around current node */ + } + } +#if OS_TASK_DEL_EN > 0u + ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; + ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; +#endif +} +#endif + diff --git a/UCOS/CORE/os_mbox.c b/UCOS/CORE/os_mbox.c new file mode 100644 index 0000000..506b023 --- /dev/null +++ b/UCOS/CORE/os_mbox.c @@ -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 +#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 */ + diff --git a/UCOS/CORE/os_mem.c b/UCOS/CORE/os_mem.c new file mode 100644 index 0000000..6a92363 --- /dev/null +++ b/UCOS/CORE/os_mem.c @@ -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 +#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 */ + diff --git a/UCOS/CORE/os_mutex.c b/UCOS/CORE/os_mutex.c new file mode 100644 index 0000000..c34f38c --- /dev/null +++ b/UCOS/CORE/os_mutex.c @@ -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 +#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 */ + diff --git a/UCOS/CORE/os_q.c b/UCOS/CORE/os_q.c new file mode 100644 index 0000000..e00da5c --- /dev/null +++ b/UCOS/CORE/os_q.c @@ -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 +#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 */ + diff --git a/UCOS/CORE/os_sem.c b/UCOS/CORE/os_sem.c new file mode 100644 index 0000000..24ca6cf --- /dev/null +++ b/UCOS/CORE/os_sem.c @@ -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 +#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 */ + diff --git a/UCOS/CORE/os_task.c b/UCOS/CORE/os_task.c new file mode 100644 index 0000000..e4a459b --- /dev/null +++ b/UCOS/CORE/os_task.c @@ -0,0 +1,1263 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* TASK MANAGEMENT +* +* (c) Copyright 1992-2009, Micrium, Weston, FL +* All Rights Reserved +* +* File : OS_TASK.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 +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CHANGE PRIORITY OF A TASK +* +* Description: This function allows you to change the priority of a task dynamically. Note that the new +* priority MUST be available. +* +* Arguments : oldp is the old priority +* +* newp is the new priority +* +* Returns : OS_ERR_NONE is the call was successful +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_PRIO_EXIST if the new priority already exist. +* OS_ERR_PRIO there is no task with the specified OLD priority (i.e. the OLD task does +* not exist. +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP. +********************************************************************************************************* +*/ + +#if OS_TASK_CHANGE_PRIO_EN > 0u +INT8U OSTaskChangePrio (INT8U oldprio, + INT8U newprio) +{ +#if (OS_EVENT_EN) + OS_EVENT *pevent; +#if (OS_EVENT_MULTI_EN > 0u) + OS_EVENT **pevents; +#endif +#endif + OS_TCB *ptcb; + INT8U y_new; + INT8U x_new; + INT8U y_old; + OS_PRIO bity_new; + OS_PRIO bitx_new; + OS_PRIO bity_old; + OS_PRIO bitx_old; +#if OS_CRITICAL_METHOD == 3u + OS_CPU_SR cpu_sr = 0u; /* Storage for CPU status register */ +#endif + + +/*$PAGE*/ +#if OS_ARG_CHK_EN > 0u + if (oldprio >= OS_LOWEST_PRIO) { + if (oldprio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (newprio >= OS_LOWEST_PRIO) { + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); + } + if (oldprio == OS_PRIO_SELF) { /* See if changing self */ + oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ + } + ptcb = OSTCBPrioTbl[oldprio]; + if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Is task assigned to Mutex */ + OS_EXIT_CRITICAL(); /* No, can't change its priority! */ + return (OS_ERR_TASK_NOT_EXIST); + } +#if OS_LOWEST_PRIO <= 63u + y_new = (INT8U)(newprio >> 3u); /* Yes, compute new TCB fields */ + x_new = (INT8U)(newprio & 0x07u); +#else + y_new = (INT8U)((INT8U)(newprio >> 4u) & 0x0Fu); + x_new = (INT8U)(newprio & 0x0Fu); +#endif + bity_new = (OS_PRIO)(1uL << y_new); + bitx_new = (OS_PRIO)(1uL << x_new); + + OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ + OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ + y_old = ptcb->OSTCBY; + bity_old = ptcb->OSTCBBitY; + bitx_old = ptcb->OSTCBBitX; + if ((OSRdyTbl[y_old] & bitx_old) != 0u) { /* If task is ready make it not */ + OSRdyTbl[y_old] &= (OS_PRIO)~bitx_old; + if (OSRdyTbl[y_old] == 0u) { + OSRdyGrp &= (OS_PRIO)~bity_old; + } + OSRdyGrp |= bity_new; /* Make new priority ready to run */ + OSRdyTbl[y_new] |= bitx_new; + } + +#if (OS_EVENT_EN) + pevent = ptcb->OSTCBEventPtr; + if (pevent != (OS_EVENT *)0) { + pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old; /* Remove old task prio from wait list */ + if (pevent->OSEventTbl[y_old] == 0u) { + pevent->OSEventGrp &= (OS_PRIO)~bity_old; + } + pevent->OSEventGrp |= bity_new; /* Add new task prio to wait list */ + pevent->OSEventTbl[y_new] |= bitx_new; + } +#if (OS_EVENT_MULTI_EN > 0u) + if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { + pevents = ptcb->OSTCBEventMultiPtr; + pevent = *pevents; + while (pevent != (OS_EVENT *)0) { + pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old; /* Remove old task prio from wait lists */ + if (pevent->OSEventTbl[y_old] == 0u) { + pevent->OSEventGrp &= (OS_PRIO)~bity_old; + } + pevent->OSEventGrp |= bity_new; /* Add new task prio to wait lists */ + pevent->OSEventTbl[y_new] |= bitx_new; + pevents++; + pevent = *pevents; + } + } +#endif +#endif + + ptcb->OSTCBPrio = newprio; /* Set new task priority */ + ptcb->OSTCBY = y_new; + ptcb->OSTCBX = x_new; + ptcb->OSTCBBitY = bity_new; + ptcb->OSTCBBitX = bitx_new; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pstk' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EN > 0u +INT8U OSTaskCreate (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio) +{ + OS_STK *psp; + INT8U err; +#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 OS_ARG_CHK_EN > 0u + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0u) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + psp = OSTaskStkInit(task, p_arg, ptos, 0u); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, (OS_STK *)0, 0u, 0u, (void *)0, 0u); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* CREATE A TASK (Extended Version) +* +* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either +* be created prior to the start of multitasking or by a running task. A task cannot be +* created by an ISR. This function is similar to OSTaskCreate() except that it allows +* additional information about a task to be specified. +* +* Arguments : task is a pointer to the task's code +* +* p_arg is a pointer to an optional data area which can be used to pass parameters to +* the task when the task first executes. Where the task is concerned it thinks +* it was invoked and passed the argument 'p_arg' as follows: +* +* void Task (void *p_arg) +* { +* for (;;) { +* Task code; +* } +* } +* +* ptos is a pointer to the task's top of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'ptos' will thus point to the highest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'ptos' will point to the +* lowest memory location of the stack and the stack will grow with increasing +* memory locations. 'ptos' MUST point to a valid 'free' data item. +* +* prio is the task's priority. A unique priority MUST be assigned to each task and the +* lower the number, the higher the priority. +* +* id is the task's ID (0..65535) +* +* pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* HIGHEST memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U, +* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to +* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if +* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries +* available on the stack. +* +* pext is a pointer to a user supplied memory location which is used as a TCB extension. +* For example, this user memory can hold the contents of floating-point registers +* during a context switch, the time each task takes to execute, the number of times +* the task has been switched-in, etc. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. Current choices are: +* +* OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task +* OS_TASK_OPT_STK_CLR Clear the stack when the task is created +* OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them +* during a context switch. +* +* Returns : OS_ERR_NONE if the function was successful. +* OS_PRIO_EXIT if the task priority already exist +* (each task MUST have a unique priority). +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) +* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_CREATE_EXT_EN > 0u +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt) +{ + OS_STK *psp; + INT8U err; +#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 OS_ARG_CHK_EN > 0u + if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + if (OSIntNesting > 0u) { /* Make sure we don't create the task from within an ISR */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_CREATE_ISR); + } + if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ + OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ + /* ... the same thing until task is created. */ + OS_EXIT_CRITICAL(); + +#if (OS_TASK_STAT_STK_CHK_EN > 0u) + OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */ +#endif + + psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */ + err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); + if (err == OS_ERR_NONE) { + if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */ + OS_Sched(); + } + } else { + OS_ENTER_CRITICAL(); + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ + OS_EXIT_CRITICAL(); + } + return (err); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO_EXIST); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* DELETE A TASK +* +* Description: This function allows you to delete a task. The calling task can delete itself by +* its own priority number. The deleted task is returned to the dormant state and can be +* re-activated by creating the deleted task again. +* +* Arguments : prio is the priority of the task to delete. Note that you can explicitely delete +* the current task without knowing its priority level by setting 'prio' to +* OS_PRIO_SELF. +* +* Returns : OS_ERR_NONE if the call is successful +* OS_ERR_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex PIP. +* OS_ERR_TASK_NOT_EXIST if the task you want to delete does not exist. +* OS_ERR_TASK_DEL_ISR if you tried to delete a task from an ISR +* +* Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task: +* a) by making it not ready +* b) by removing it from any wait lists +* c) by preventing OSTimeTick() from making the task ready to run. +* The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II. +* 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors, +* the next instruction following the enable interrupt instruction is ignored. +* 3) An ISR cannot delete a task. +* 4) The lock nesting counter is incremented because, for a brief instant, if the current +* task is being deleted, the current task would not be able to be rescheduled because it +* is removed from the ready list. Incrementing the nesting counter prevents another task +* from being schedule. This means that an ISR would return to the current task which is +* being deleted. The rest of the deletion would thus be able to be completed. +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0u +INT8U OSTaskDel (INT8U prio) +{ +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) + OS_FLAG_NODE *pnode; +#endif + OS_TCB *ptcb; +#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 delete from ISR */ + return (OS_ERR_TASK_DEL_ISR); + } + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0u + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + +/*$PAGE*/ + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */ + prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { /* Must not be assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + + OSRdyTbl[ptcb->OSTCBY] &= (OS_PRIO)~ptcb->OSTCBBitX; + if (OSRdyTbl[ptcb->OSTCBY] == 0u) { /* Make task not ready */ + OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY; + } + +#if (OS_EVENT_EN) + if (ptcb->OSTCBEventPtr != (OS_EVENT *)0) { + OS_EventTaskRemove(ptcb, ptcb->OSTCBEventPtr); /* Remove this task from any event wait list */ + } +#if (OS_EVENT_MULTI_EN > 0u) + if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { /* Remove this task from any events' wait lists*/ + OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr); + } +#endif +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) + pnode = ptcb->OSTCBFlagNode; + if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */ + OS_FlagUnlink(pnode); /* Remove from wait list */ + } +#endif + + ptcb->OSTCBDly = 0u; /* Prevent OSTimeTick() from updating */ + ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */ + ptcb->OSTCBStatPend = OS_STAT_PEND_OK; + if (OSLockNesting < 255u) { /* Make sure we don't context switch */ + OSLockNesting++; + } + OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */ + OS_Dummy(); /* ... Dummy ensures that INTs will be */ + OS_ENTER_CRITICAL(); /* ... disabled HERE! */ + if (OSLockNesting > 0u) { /* Remove context switch lock */ + OSLockNesting--; + } + OSTaskDelHook(ptcb); /* Call user defined hook */ + OSTaskCtr--; /* One less task being managed */ + OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */ + if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */ + ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; + OSTCBList = ptcb->OSTCBNext; + } else { + ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; + ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; + } + ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */ + OSTCBFreeList = ptcb; +#if OS_TASK_NAME_EN > 0u + ptcb->OSTCBTaskName = (INT8U *)(void *)"?"; +#endif + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* REQUEST THAT A TASK DELETE ITSELF +* +* Description: This function is used to: +* a) notify a task to delete itself. +* b) to see if a task requested that the current task delete itself. +* This function is a little tricky to understand. Basically, you have a task that needs +* to be deleted however, this task has resources that it has allocated (memory buffers, +* semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these +* resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that +* the task needs to be deleted. Deleting of the task is however, deferred to the task to +* be deleted. For example, suppose that task #10 needs to be deleted. The requesting task +* example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls +* this function by specifying OS_PRIO_SELF and monitors the returned value. If the return +* value is OS_ERR_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like +* this: +* +* void Task(void *p_arg) +* { +* . +* . +* while (1) { +* OSTimeDly(1); +* if (OSTaskDelReq(OS_PRIO_SELF) == OS_ERR_TASK_DEL_REQ) { +* Release any owned resources; +* De-allocate any dynamic memory; +* OSTaskDel(OS_PRIO_SELF); +* } +* } +* } +* +* Arguments : prio is the priority of the task to request the delete from +* +* Returns : OS_ERR_NONE if the task exist and the request has been registered +* OS_ERR_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether +* the request has been executed. +* OS_ERR_TASK_DEL if the task is assigned to a Mutex. +* OS_ERR_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_DEL_REQ if a task (possibly another task) requested that the running task be +* deleted. +********************************************************************************************************* +*/ +/*$PAGE*/ +#if OS_TASK_DEL_EN > 0u +INT8U OSTaskDelReq (INT8U prio) +{ + INT8U stat; + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + + if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ + return (OS_ERR_TASK_DEL_IDLE); + } +#if OS_ARG_CHK_EN > 0u + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */ + OS_ENTER_CRITICAL(); /* ... this task to delete itself */ + stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */ + OS_EXIT_CRITICAL(); + return (stat); + } + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); /* Task must already be deleted */ + } + if (ptcb == OS_TCB_RESERVED) { /* Must NOT be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_DEL); + } + ptcb->OSTCBDelReq = OS_ERR_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */ + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE NAME OF A TASK +* +* Description: This function is called to obtain the name of a task. +* +* Arguments : prio is the priority of the task that you want to obtain the name from. +* +* pname is a pointer to a pointer to an ASCII string that will receive the name of the task. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* 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 the task does not exist. +********************************************************************************************************* +*/ + +#if OS_TASK_NAME_EN > 0u +INT8U OSTaskNameGet (INT8U prio, + INT8U **pname, + INT8U *perr) +{ + OS_TCB *ptcb; + 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 (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return (0u); + } + } + if (pname == (INT8U **)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + 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(); + if (prio == OS_PRIO_SELF) { /* See if caller desires it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0u); + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return (0u); + } + *pname = ptcb->OSTCBTaskName; + len = OS_StrLen(*pname); + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (len); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* ASSIGN A NAME TO A TASK +* +* Description: This function is used to set the name of a task. +* +* Arguments : prio is the priority of the task that you want the assign a name to. +* +* pname is a pointer to an ASCII string that contains the name of the task. +* +* perr is a pointer to an error code that can contain one of the following values: +* +* OS_ERR_NONE if the requested task is resumed +* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex +* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname' +* OS_ERR_PRIO_INVALID if you specified an invalid priority: +* A higher value than the idle task or not OS_PRIO_SELF. +* OS_ERR_NAME_SET_ISR if you called this function from an ISR +* +* Returns : None +********************************************************************************************************* +*/ +#if OS_TASK_NAME_EN > 0u +void OSTaskNameSet (INT8U prio, + INT8U *pname, + INT8U *perr) +{ + 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 (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; /* No */ + return; + } + } + if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ + *perr = OS_ERR_PNAME_NULL; /* Yes */ + return; + } +#endif + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_SET_ISR; + return; + } + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Does task exist? */ + OS_EXIT_CRITICAL(); /* No */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */ + OS_EXIT_CRITICAL(); /* Yes */ + *perr = OS_ERR_TASK_NOT_EXIST; + return; + } + ptcb->OSTCBTaskName = pname; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* RESUME A SUSPENDED TASK +* +* Description: This function is called to resume a previously suspended task. This is the only call that +* will remove an explicit task suspension. +* +* Arguments : prio is the priority of the task to resume. +* +* Returns : OS_ERR_NONE if the requested task is resumed +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) +* OS_ERR_TASK_RESUME_PRIO if the task to resume does not exist +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_TASK_NOT_SUSPENDED if the task to resume has not been suspended +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0u +INT8U OSTaskResume (INT8U prio) +{ + OS_TCB *ptcb; +#if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + + + +#if OS_ARG_CHK_EN > 0u + if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + return (OS_ERR_PRIO_INVALID); + } +#endif + OS_ENTER_CRITICAL(); + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_RESUME_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */ + ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_SUSPEND; /* Remove suspension */ + if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is now ready */ + if (ptcb->OSTCBDly == 0u) { + OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */ + OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; + OS_EXIT_CRITICAL(); + if (OSRunning == OS_TRUE) { + OS_Sched(); /* Find new highest priority task */ + } + } else { + OS_EXIT_CRITICAL(); + } + } else { /* Must be pending on event */ + OS_EXIT_CRITICAL(); + } + return (OS_ERR_NONE); + } + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_SUSPENDED); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* STACK CHECKING +* +* Description: This function is called to check the amount of free memory left on the specified task's +* stack. +* +* Arguments : prio is the task priority +* +* p_stk_data is a pointer to a data structure of type OS_STK_DATA. +* +* Returns : OS_ERR_NONE upon success +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP +* OS_ERR_TASK_OPT if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created +* OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer +********************************************************************************************************* +*/ +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +INT8U OSTaskStkChk (INT8U prio, + OS_STK_DATA *p_stk_data) +{ + OS_TCB *ptcb; + OS_STK *pchk; + INT32U nfree; + INT32U size; +#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 (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_stk_data == (OS_STK_DATA *)0) { /* Validate 'p_stk_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + p_stk_data->OSFree = 0u; /* Assume failure, set to 0 size */ + p_stk_data->OSUsed = 0u; + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if check for SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Make sure task exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if (ptcb == OS_TCB_RESERVED) { + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0u) { /* Make sure stack checking option is set */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_OPT); + } + nfree = 0u; + size = ptcb->OSTCBStkSize; + pchk = ptcb->OSTCBStkBottom; + OS_EXIT_CRITICAL(); +#if OS_STK_GROWTH == 1u + while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */ + nfree++; + } +#else + while (*pchk-- == (OS_STK)0) { + nfree++; + } +#endif + p_stk_data->OSFree = nfree * sizeof(OS_STK); /* Compute number of free bytes on the stack */ + p_stk_data->OSUsed = (size - nfree) * sizeof(OS_STK); /* Compute number of bytes used on the stack */ + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* SUSPEND A TASK +* +* Description: This function is called to suspend a task. The task can be the calling task if the +* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF. +* +* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the +* calling task will suspend itself and rescheduling will occur. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed. +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_TASK_SUSPEND_PRIO if the task to suspend does not exist +* OS_ERR_TASK_NOT_EXITS if the task is assigned to a Mutex PIP +* +* Note : You should use this function with great care. If you suspend a task that is waiting for +* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from +* running when the event arrives. +********************************************************************************************************* +*/ + +#if OS_TASK_SUSPEND_EN > 0u +INT8U OSTaskSuspend (INT8U prio) +{ + BOOLEAN self; + OS_TCB *ptcb; + INT8U y; +#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 (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to suspend idle task */ + return (OS_ERR_TASK_SUSPEND_IDLE); + } + if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + self = OS_TRUE; + } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */ + self = OS_TRUE; + } else { + self = OS_FALSE; /* No suspending another task */ + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_SUSPEND_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + y = ptcb->OSTCBY; + OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Make task not ready */ + if (OSRdyTbl[y] == 0u) { + OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY; + } + ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */ + OS_EXIT_CRITICAL(); + if (self == OS_TRUE) { /* Context switch only if SELF */ + OS_Sched(); /* Find new highest priority task */ + } + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* QUERY A TASK +* +* Description: This function is called to obtain a copy of the desired task's TCB. +* +* Arguments : prio is the priority of the task to obtain information from. +* +* p_task_data is a pointer to where the desired task's OS_TCB will be stored. +* +* Returns : OS_ERR_NONE if the requested task is suspended +* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed +* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF. +* OS_ERR_PRIO if the desired task has not been created +* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP +* OS_ERR_PDATA_NULL if 'p_task_data' is a NULL pointer +********************************************************************************************************* +*/ + +#if OS_TASK_QUERY_EN > 0u +INT8U OSTaskQuery (INT8U prio, + OS_TCB *p_task_data) +{ + OS_TCB *ptcb; +#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 (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */ + if (prio != OS_PRIO_SELF) { + return (OS_ERR_PRIO_INVALID); + } + } + if (p_task_data == (OS_TCB *)0) { /* Validate 'p_task_data' */ + return (OS_ERR_PDATA_NULL); + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ + prio = OSTCBCur->OSTCBPrio; + } + ptcb = OSTCBPrioTbl[prio]; + if (ptcb == (OS_TCB *)0) { /* Task to query must exist */ + OS_EXIT_CRITICAL(); + return (OS_ERR_PRIO); + } + if (ptcb == OS_TCB_RESERVED) { /* Task to query must not be assigned to a Mutex */ + OS_EXIT_CRITICAL(); + return (OS_ERR_TASK_NOT_EXIST); + } + /* Copy TCB into user storage area */ + OS_MemCopy((INT8U *)p_task_data, (INT8U *)ptcb, sizeof(OS_TCB)); + OS_EXIT_CRITICAL(); + return (OS_ERR_NONE); +} +#endif +/*$PAGE*/ +/* +********************************************************************************************************* +* GET THE CURRENT VALUE OF A TASK REGISTER +* +* Description: This function is called to obtain the current value of a task register. Task registers +* are application specific and can be used to store task specific values such as 'error +* numbers' (i.e. errno), statistics, etc. Each task register can hold a 32-bit value. +* +* Arguments : prio is the priority of the task you want to get the task register from. If you +* specify OS_PRIO_SELF then the task register of the current task will be obtained. +* +* id is the 'id' of the desired task register. Note that the 'id' must be less +* than OS_TASK_REG_TBL_SIZE +* +* perr is a pointer to a variable that will hold an error code related to this call. +* +* OS_ERR_NONE if the call was successful +* OS_ERR_PRIO_INVALID if you specified an invalid priority +* OS_ERR_ID_INVALID if the 'id' is not between 0 and OS_TASK_REG_TBL_SIZE-1 +* +* Returns : The current value of the task's register or 0 if an error is detected. +* +* Note(s) : The maximum number of task variables is 254 +********************************************************************************************************* +*/ + +#if OS_TASK_REG_TBL_SIZE > 0u +INT32U OSTaskRegGet (INT8U prio, + INT8U id, + INT8U *perr) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + INT32U value; + OS_TCB *ptcb; + + +#if OS_ARG_CHK_EN > 0u + if (prio >= OS_LOWEST_PRIO) { + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; + return (0u); + } + } + if (id >= OS_TASK_REG_TBL_SIZE) { + *perr = OS_ERR_ID_INVALID; + return (0u); + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if need to get register from current task */ + ptcb = OSTCBCur; + } else { + ptcb = OSTCBPrioTbl[prio]; + } + value = ptcb->OSTCBRegTbl[id]; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; + return (value); +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SET THE CURRENT VALUE OF A TASK VARIABLE +* +* Description: This function is called to change the current value of a task register. Task registers +* are application specific and can be used to store task specific values such as 'error +* numbers' (i.e. errno), statistics, etc. Each task register can hold a 32-bit value. +* +* Arguments : prio is the priority of the task you want to set the task register for. If you +* specify OS_PRIO_SELF then the task register of the current task will be obtained. +* +* id is the 'id' of the desired task register. Note that the 'id' must be less +* than OS_TASK_REG_TBL_SIZE +* +* value is the desired value for the task register. +* +* perr is a pointer to a variable that will hold an error code related to this call. +* +* OS_ERR_NONE if the call was successful +* OS_ERR_PRIO_INVALID if you specified an invalid priority +* OS_ERR_ID_INVALID if the 'id' is not between 0 and OS_TASK_REG_TBL_SIZE-1 +* +* Returns : The current value of the task's variable or 0 if an error is detected. +* +* Note(s) : The maximum number of task variables is 254 +********************************************************************************************************* +*/ + +#if OS_TASK_REG_TBL_SIZE > 0u +void OSTaskRegSet (INT8U prio, + INT8U id, + INT32U value, + INT8U *perr) +{ +#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ + OS_CPU_SR cpu_sr = 0u; +#endif + OS_TCB *ptcb; + + +#if OS_ARG_CHK_EN > 0u + if (prio >= OS_LOWEST_PRIO) { + if (prio != OS_PRIO_SELF) { + *perr = OS_ERR_PRIO_INVALID; + return; + } + } + if (id >= OS_TASK_REG_TBL_SIZE) { + *perr = OS_ERR_ID_INVALID; + return; + } +#endif + OS_ENTER_CRITICAL(); + if (prio == OS_PRIO_SELF) { /* See if need to get register from current task */ + ptcb = OSTCBCur; + } else { + ptcb = OSTCBPrioTbl[prio]; + } + ptcb->OSTCBRegTbl[id] = value; + OS_EXIT_CRITICAL(); + *perr = OS_ERR_NONE; +} +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* CATCH ACCIDENTAL TASK RETURN +* +* Description: This function is called if a task accidentally returns without deleting itself. In other +* words, a task should either be an infinite loop or delete itself if it's done. +* +* Arguments : none +* +* Returns : none +* +* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it. +********************************************************************************************************* +*/ + +void OS_TaskReturn (void) +{ + OSTaskReturnHook(OSTCBCur); /* Call hook to let user decide on what to do */ + +#if OS_TASK_DEL_EN > 0u + (void)OSTaskDel(OS_PRIO_SELF); /* Delete task if it accidentally returns! */ +#else + for (;;) { + OSTimeDly(OS_TICKS_PER_SEC); + } +#endif +} + +/*$PAGE*/ +/* +********************************************************************************************************* +* CLEAR TASK STACK +* +* Description: This function is used to clear the stack of a task (i.e. write all zeros) +* +* Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant +* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high +* memory to low memory). 'pbos' will thus point to the lowest (valid) memory +* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the +* highest memory location of the stack and the stack will grow with increasing +* memory locations. 'pbos' MUST point to a valid 'free' data item. +* +* size is the number of 'stack elements' to clear. +* +* opt contains additional information (or options) about the behavior of the task. The +* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application +* specific. See OS_TASK_OPT_??? in uCOS-II.H. +* +* Returns : none +********************************************************************************************************* +*/ +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +void OS_TaskStkClr (OS_STK *pbos, + INT32U size, + INT16U opt) +{ + if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000u) { /* See if stack checking has been enabled */ + if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000u) { /* See if stack needs to be cleared */ +#if OS_STK_GROWTH == 1u + while (size > 0u) { /* Stack grows from HIGH to LOW memory */ + size--; + *pbos++ = (OS_STK)0; /* Clear from bottom of stack and up! */ + } +#else + while (size > 0u) { /* Stack grows from LOW to HIGH memory */ + size--; + *pbos-- = (OS_STK)0; /* Clear from bottom of stack and down */ + } +#endif + } + } +} + +#endif + diff --git a/UCOS/CORE/os_time.c b/UCOS/CORE/os_time.c new file mode 100644 index 0000000..1826ffa --- /dev/null +++ b/UCOS/CORE/os_time.c @@ -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 +#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 + diff --git a/UCOS/CORE/os_tmr.c b/UCOS/CORE/os_tmr.c new file mode 100644 index 0000000..cf7b690 --- /dev/null +++ b/UCOS/CORE/os_tmr.c @@ -0,0 +1,1073 @@ +/* +************************************************************************************************************************ +* uC/OS-II +* The Real-Time Kernel +* TIMER MANAGEMENT +* +* (c) Copyright 1992-2009, Micrium, Weston, FL +* All Rights Reserved +* +* +* File : OS_TMR.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. +************************************************************************************************************************ +*/ + +#include + +/* +************************************************************************************************************************ +* NOTES +* +* 1) Your application MUST define the following #define constants: +* +* OS_TASK_TMR_PRIO The priority of the Timer management task +* OS_TASK_TMR_STK_SIZE The size of the Timer management task's stack +* +* 2) You must call OSTmrSignal() to notify the Timer management task that it's time to update the timers. +************************************************************************************************************************ +*/ + +/* +************************************************************************************************************************ +* CONSTANTS +************************************************************************************************************************ +*/ + +#define OS_TMR_LINK_DLY 0u +#define OS_TMR_LINK_PERIODIC 1u + +/* +************************************************************************************************************************ +* LOCAL PROTOTYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static OS_TMR *OSTmr_Alloc (void); +static void OSTmr_Free (OS_TMR *ptmr); +static void OSTmr_InitTask (void); +static void OSTmr_Link (OS_TMR *ptmr, INT8U type); +static void OSTmr_Unlink (OS_TMR *ptmr); +static void OSTmr_Task (void *p_arg); +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* CREATE A TIMER +* +* Description: This function is called by your application code to create a timer. +* +* Arguments : dly Initial delay. +* If the timer is configured for ONE-SHOT mode, this is the timeout used +* If the timer is configured for PERIODIC mode, this is the first timeout to wait for +* before the timer starts entering periodic mode +* +* period The 'period' being repeated for the timer. +* If you specified 'OS_TMR_OPT_PERIODIC' as an option, when the timer expires, it will +* automatically restart with the same period. +* +* opt Specifies either: +* OS_TMR_OPT_ONE_SHOT The timer counts down only once +* OS_TMR_OPT_PERIODIC The timer counts down and then reloads itself +* +* callback Is a pointer to a callback function that will be called when the timer expires. The +* callback function must be declared as follows: +* +* void MyCallback (OS_TMR *ptmr, void *p_arg); +* +* callback_arg Is an argument (a pointer) that is passed to the callback function when it is called. +* +* pname Is a pointer to an ASCII string that is used to name the timer. Names are useful for +* debugging. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID_DLY you specified an invalid delay +* OS_ERR_TMR_INVALID_PERIOD you specified an invalid period +* OS_ERR_TMR_INVALID_OPT you specified an invalid option +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_NON_AVAIL if there are no free timers from the timer pool +* +* Returns : A pointer to an OS_TMR data structure. +* This is the 'handle' that your application will use to reference the timer created. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr) +{ + OS_TMR *ptmr; + + +#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 + switch (opt) { /* Validate arguments */ + case OS_TMR_OPT_PERIODIC: + if (period == 0u) { + *perr = OS_ERR_TMR_INVALID_PERIOD; + return ((OS_TMR *)0); + } + break; + + case OS_TMR_OPT_ONE_SHOT: + if (dly == 0u) { + *perr = OS_ERR_TMR_INVALID_DLY; + return ((OS_TMR *)0); + } + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + return ((OS_TMR *)0); + } +#endif + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return ((OS_TMR *)0); + } + OSSchedLock(); + ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */ + if (ptmr == (OS_TMR *)0) { + OSSchedUnlock(); + *perr = OS_ERR_TMR_NON_AVAIL; + return ((OS_TMR *)0); + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; /* Indicate that timer is not running yet */ + ptmr->OSTmrDly = dly; + ptmr->OSTmrPeriod = period; + ptmr->OSTmrOpt = opt; + ptmr->OSTmrCallback = callback; + ptmr->OSTmrCallbackArg = callback_arg; +#if OS_TMR_CFG_NAME_EN > 0u + ptmr->OSTmrName = pname; +#endif + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (ptmr); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* DELETE A TIMER +* +* Description: This function is called by your application code to delete a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop and delete. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE If the call was successful +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr) +{ +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSSchedLock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Timer has not started or ... */ + case OS_TMR_STATE_COMPLETED: /* ... timer has completed the ONE-SHOT time */ + OSTmr_Free(ptmr); /* Return timer to free list of timers */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Already deleted */ + OSSchedUnlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET THE NAME OF A TIMER +* +* Description: This function is called to obtain the name of a timer. +* +* Arguments : ptmr Is a pointer to the timer to obtain the name for +* +* pdest Is a pointer to pointer to where the name of the timer will be placed. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE The call was successful +* OS_ERR_TMR_INVALID_DEST 'pdest' is a NULL pointer +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_NAME_GET_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The length of the string or 0 if the timer does not exist. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u && OS_TMR_CFG_NAME_EN > 0u +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U **pdest, + INT8U *perr) +{ + INT8U len; + + +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (pdest == (INT8U **)0) { + *perr = OS_ERR_TMR_INVALID_DEST; + return (0u); + } + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0u); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0u); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_NAME_GET_ISR; + return (0u); + } + OSSchedLock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + *pdest = ptmr->OSTmrName; + len = OS_StrLen(*pdest); + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (len); + + case OS_TMR_STATE_UNUSED: /* Timer is not allocated */ + OSSchedUnlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0u); + + default: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0u); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* GET HOW MUCH TIME IS LEFT BEFORE A TIMER EXPIRES +* +* Description: This function is called to get the number of ticks before a timer times out. +* +* Arguments : ptmr Is a pointer to the timer to obtain the remaining time from. +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : The time remaining for the timer to expire. The time represents 'timer' increments. In other words, if +* OSTmr_Task() is signaled every 1/10 of a second then the returned value represents the number of 1/10 of +* a second remaining before the timer expires. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT32U remain; + + +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0u); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0u); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0u); + } + OSSchedLock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + remain = ptmr->OSTmrMatch - OSTmrTime; /* Determine how much time is left to timeout */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (remain); + + case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */ + switch (ptmr->OSTmrOpt) { + case OS_TMR_OPT_PERIODIC: + if (ptmr->OSTmrDly == 0u) { + remain = ptmr->OSTmrPeriod; + } else { + remain = ptmr->OSTmrDly; + } + OSSchedUnlock(); + *perr = OS_ERR_NONE; + break; + + case OS_TMR_OPT_ONE_SHOT: + default: + remain = ptmr->OSTmrDly; + OSSchedUnlock(); + *perr = OS_ERR_NONE; + break; + } + return (remain); + + case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (0u); + + case OS_TMR_STATE_UNUSED: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (0u); + + default: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (0u); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* FIND OUT WHAT STATE A TIMER IS IN +* +* Description: This function is called to determine what state the timer is in: +* +* OS_TMR_STATE_UNUSED the timer has not been created +* OS_TMR_STATE_STOPPED the timer has been created but has not been started or has been stopped +* OS_TMR_COMPLETED the timer is in ONE-SHOT mode and has completed it's timeout +* OS_TMR_RUNNING the timer is currently running +* +* Arguments : ptmr Is a pointer to the desired timer +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE 'ptmr' points to a timer that is not active +* OS_ERR_TMR_INVALID_STATE if the timer is not in a valid state +* +* Returns : The current state of the timer (see description). +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr) +{ + INT8U state; + + +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (0u); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (0u); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (0u); + } + OSSchedLock(); + state = ptmr->OSTmrState; + switch (state) { + case OS_TMR_STATE_UNUSED: + case OS_TMR_STATE_STOPPED: + case OS_TMR_STATE_COMPLETED: + case OS_TMR_STATE_RUNNING: + *perr = OS_ERR_NONE; + break; + + default: + *perr = OS_ERR_TMR_INVALID_STATE; + break; + } + OSSchedUnlock(); + return (state); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* START A TIMER +* +* Description: This function is called by your application code to start a timer. +* +* Arguments : ptmr Is a pointer to an OS_TMR +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the call was made from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* +* Returns : OS_TRUE if the timer was started +* OS_FALSE if an error was detected +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr) +{ +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSSchedLock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: /* Restart the timer */ + OSTmr_Unlink(ptmr); /* ... Stop the timer */ + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_STOPPED: /* Start the timer */ + case OS_TMR_STATE_COMPLETED: + OSTmr_Link(ptmr, OS_TMR_LINK_DLY); /* ... Link timer to timer wheel */ + OSSchedUnlock(); + *perr = OS_ERR_NONE; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer not created */ + OSSchedUnlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* STOP A TIMER +* +* Description: This function is called by your application code to stop a timer. +* +* Arguments : ptmr Is a pointer to the timer to stop. +* +* opt Allows you to specify an option to this functions which can be: +* +* OS_TMR_OPT_NONE Do nothing special but stop the timer +* OS_TMR_OPT_CALLBACK Execute the callback function, pass it the callback argument +* specified when the timer was created. +* OS_TMR_OPT_CALLBACK_ARG Execute the callback function, pass it the callback argument +* specified in THIS function call +* +* callback_arg Is a pointer to a 'new' callback argument that can be passed to the callback function +* instead of the timer's callback argument. In other words, use 'callback_arg' passed in +* THIS function INSTEAD of ptmr->OSTmrCallbackArg +* +* perr Is a pointer to an error code. '*perr' will contain one of the following: +* OS_ERR_NONE +* OS_ERR_TMR_INVALID 'ptmr' is a NULL pointer +* OS_ERR_TMR_INVALID_TYPE 'ptmr' is not pointing to an OS_TMR +* OS_ERR_TMR_ISR if the function was called from an ISR +* OS_ERR_TMR_INACTIVE if the timer was not created +* OS_ERR_TMR_INVALID_OPT if you specified an invalid option for 'opt' +* OS_ERR_TMR_STOPPED if the timer was already stopped +* OS_ERR_TMR_INVALID_STATE the timer is in an invalid state +* OS_ERR_TMR_NO_CALLBACK if the timer does not have a callback function defined +* +* Returns : OS_TRUE If we stopped the timer (if the timer is already stopped, we also return OS_TRUE) +* OS_FALSE If not +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr) +{ + OS_TMR_CALLBACK pfnct; + + +#ifdef OS_SAFETY_CRITICAL + if (perr == (INT8U *)0) { + OS_SAFETY_CRITICAL_EXCEPTION(); + } +#endif + +#if OS_ARG_CHK_EN > 0u + if (ptmr == (OS_TMR *)0) { + *perr = OS_ERR_TMR_INVALID; + return (OS_FALSE); + } +#endif + if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ + *perr = OS_ERR_TMR_INVALID_TYPE; + return (OS_FALSE); + } + if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ + *perr = OS_ERR_TMR_ISR; + return (OS_FALSE); + } + OSSchedLock(); + switch (ptmr->OSTmrState) { + case OS_TMR_STATE_RUNNING: + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + *perr = OS_ERR_NONE; + switch (opt) { + case OS_TMR_OPT_CALLBACK: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); /* Use callback arg when timer was created */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_CALLBACK_ARG: + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, callback_arg); /* ... using the 'callback_arg' provided in call */ + } else { + *perr = OS_ERR_TMR_NO_CALLBACK; + } + break; + + case OS_TMR_OPT_NONE: + break; + + default: + *perr = OS_ERR_TMR_INVALID_OPT; + break; + } + OSSchedUnlock(); + return (OS_TRUE); + + case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or ... */ + case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ + OSSchedUnlock(); + *perr = OS_ERR_TMR_STOPPED; + return (OS_TRUE); + + case OS_TMR_STATE_UNUSED: /* Timer was not created */ + OSSchedUnlock(); + *perr = OS_ERR_TMR_INACTIVE; + return (OS_FALSE); + + default: + OSSchedUnlock(); + *perr = OS_ERR_TMR_INVALID_STATE; + return (OS_FALSE); + } +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* SIGNAL THAT IT'S TIME TO UPDATE THE TIMERS +* +* Description: This function is typically called by the ISR that occurs at the timer tick rate and is used to signal to +* OSTmr_Task() that it's time to update the timers. +* +* Arguments : none +* +* Returns : OS_ERR_NONE The call was successful and the timer task was signaled. +* OS_ERR_SEM_OVF If OSTmrSignal() was called more often than OSTmr_Task() can handle the timers. +* This would indicate that your system is heavily loaded. +* OS_ERR_EVENT_TYPE Unlikely you would get this error because the semaphore used for signaling is created +* by uC/OS-II. +* OS_ERR_PEVENT_NULL Again, unlikely you would ever get this error because the semaphore used for signaling +* is created by uC/OS-II. +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +INT8U OSTmrSignal (void) +{ + INT8U err; + + + err = OSSemPost(OSTmrSemSignal); + return (err); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* ALLOCATE AND FREE A TIMER +* +* Description: This function is called to allocate a timer. +* +* Arguments : none +* +* Returns : a pointer to a timer if one is available +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static OS_TMR *OSTmr_Alloc (void) +{ + OS_TMR *ptmr; + + + if (OSTmrFreeList == (OS_TMR *)0) { + return ((OS_TMR *)0); + } + ptmr = (OS_TMR *)OSTmrFreeList; + OSTmrFreeList = (OS_TMR *)ptmr->OSTmrNext; + ptmr->OSTmrNext = (OS_TCB *)0; + ptmr->OSTmrPrev = (OS_TCB *)0; + OSTmrUsed++; + OSTmrFree--; + return (ptmr); +} +#endif + + +/* +************************************************************************************************************************ +* RETURN A TIMER TO THE FREE LIST +* +* Description: This function is called to return a timer object to the free list of timers. +* +* Arguments : ptmr is a pointer to the timer to free +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static void OSTmr_Free (OS_TMR *ptmr) +{ + ptmr->OSTmrState = OS_TMR_STATE_UNUSED; /* Clear timer object fields */ + ptmr->OSTmrOpt = OS_TMR_OPT_NONE; + ptmr->OSTmrPeriod = 0u; + ptmr->OSTmrMatch = 0u; + ptmr->OSTmrCallback = (OS_TMR_CALLBACK)0; + ptmr->OSTmrCallbackArg = (void *)0; +#if OS_TMR_CFG_NAME_EN > 0u + ptmr->OSTmrName = (INT8U *)(void *)"?"; +#endif + + ptmr->OSTmrPrev = (OS_TCB *)0; /* Chain timer to free list */ + ptmr->OSTmrNext = OSTmrFreeList; + OSTmrFreeList = ptmr; + + OSTmrUsed--; /* Update timer object statistics */ + OSTmrFree++; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZATION +* INITIALIZE THE FREE LIST OF TIMERS +* +* Description: This function is called by OSInit() to initialize the free list of OS_TMRs. +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +void OSTmr_Init (void) +{ +#if OS_EVENT_NAME_EN > 0u + INT8U err; +#endif + INT16U ix; + INT16U ix_next; + OS_TMR *ptmr1; + OS_TMR *ptmr2; + + + OS_MemClr((INT8U *)&OSTmrTbl[0], sizeof(OSTmrTbl)); /* Clear all the TMRs */ + OS_MemClr((INT8U *)&OSTmrWheelTbl[0], sizeof(OSTmrWheelTbl)); /* Clear the timer wheel */ + + for (ix = 0u; ix < (OS_TMR_CFG_MAX - 1u); ix++) { /* Init. list of free TMRs */ + ix_next = ix + 1u; + ptmr1 = &OSTmrTbl[ix]; + ptmr2 = &OSTmrTbl[ix_next]; + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)ptmr2; /* Link to next timer */ +#if OS_TMR_CFG_NAME_EN > 0u + ptmr1->OSTmrName = (INT8U *)(void *)"?"; +#endif + } + ptmr1 = &OSTmrTbl[ix]; + ptmr1->OSTmrType = OS_TMR_TYPE; + ptmr1->OSTmrState = OS_TMR_STATE_UNUSED; /* Indicate that timer is inactive */ + ptmr1->OSTmrNext = (void *)0; /* Last OS_TMR */ +#if OS_TMR_CFG_NAME_EN > 0u + ptmr1->OSTmrName = (INT8U *)(void *)"?"; +#endif + OSTmrTime = 0u; + OSTmrUsed = 0u; + OSTmrFree = OS_TMR_CFG_MAX; + OSTmrFreeList = &OSTmrTbl[0]; + OSTmrSem = OSSemCreate(1u); + OSTmrSemSignal = OSSemCreate(0u); + +#if OS_EVENT_NAME_EN > 0u /* Assign names to semaphores */ + OSEventNameSet(OSTmrSem, (INT8U *)(void *)"uC/OS-II TmrLock", &err); + OSEventNameSet(OSTmrSemSignal, (INT8U *)(void *)"uC/OS-II TmrSignal", &err); +#endif + + OSTmr_InitTask(); +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INITIALIZE THE TIMER MANAGEMENT TASK +* +* Description: This function is called by OSTmrInit() to create the timer management task. +* * Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static void OSTmr_InitTask (void) +{ +#if OS_TASK_NAME_EN > 0u + INT8U err; +#endif + + +#if OS_TASK_CREATE_EXT_EN > 0u + #if OS_STK_GROWTH == 1u + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[0], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #else + (void)OSTaskCreateExt(OSTmr_Task, + (void *)0, /* No arguments passed to OSTmrTask() */ + &OSTmrTaskStk[0], /* Set Top-Of-Stack */ + OS_TASK_TMR_PRIO, + OS_TASK_TMR_ID, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u], /* Set Bottom-Of-Stack */ + OS_TASK_TMR_STK_SIZE, + (void *)0, /* No TCB extension */ + OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */ + #endif +#else + #if OS_STK_GROWTH == 1u + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u], + OS_TASK_TMR_PRIO); + #else + (void)OSTaskCreate(OSTmr_Task, + (void *)0, + &OSTmrTaskStk[0], + OS_TASK_TMR_PRIO); + #endif +#endif + +#if OS_TASK_NAME_EN > 0u + OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)(void *)"uC/OS-II Tmr", &err); +#endif +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* INSERT A TIMER INTO THE TIMER WHEEL +* +* Description: This function is called to insert the timer into the timer wheel. The timer is always inserted at the +* beginning of the list. +* +* Arguments : ptmr Is a pointer to the timer to insert. +* +* type Is either: +* OS_TMR_LINK_PERIODIC Means to re-insert the timer after a period expired +* OS_TMR_LINK_DLY Means to insert the timer the first time +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static void OSTmr_Link (OS_TMR *ptmr, + INT8U type) +{ + OS_TMR *ptmr1; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + ptmr->OSTmrState = OS_TMR_STATE_RUNNING; + if (type == OS_TMR_LINK_PERIODIC) { /* Determine when timer will expire */ + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + if (ptmr->OSTmrDly == 0u) { + ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime; + } else { + ptmr->OSTmrMatch = ptmr->OSTmrDly + OSTmrTime; + } + } + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == (OS_TMR *)0) { /* Link into timer wheel */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (OS_TMR *)0; + pspoke->OSTmrEntries = 1u; + } else { + ptmr1 = pspoke->OSTmrFirst; /* Point to first timer in the spoke */ + pspoke->OSTmrFirst = ptmr; + ptmr->OSTmrNext = (void *)ptmr1; + ptmr1->OSTmrPrev = (void *)ptmr; + pspoke->OSTmrEntries++; + } + ptmr->OSTmrPrev = (void *)0; /* Timer always inserted as first node in list */ +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* REMOVE A TIMER FROM THE TIMER WHEEL +* +* Description: This function is called to remove the timer from the timer wheel. +* +* Arguments : ptmr Is a pointer to the timer to remove. +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static void OSTmr_Unlink (OS_TMR *ptmr) +{ + OS_TMR *ptmr1; + OS_TMR *ptmr2; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE); + pspoke = &OSTmrWheelTbl[spoke]; + + if (pspoke->OSTmrFirst == ptmr) { /* See if timer to remove is at the beginning of list */ + ptmr1 = (OS_TMR *)ptmr->OSTmrNext; + pspoke->OSTmrFirst = (OS_TMR *)ptmr1; + if (ptmr1 != (OS_TMR *)0) { + ptmr1->OSTmrPrev = (void *)0; + } + } else { + ptmr1 = (OS_TMR *)ptmr->OSTmrPrev; /* Remove timer from somewhere in the list */ + ptmr2 = (OS_TMR *)ptmr->OSTmrNext; + ptmr1->OSTmrNext = ptmr2; + if (ptmr2 != (OS_TMR *)0) { + ptmr2->OSTmrPrev = (void *)ptmr1; + } + } + ptmr->OSTmrState = OS_TMR_STATE_STOPPED; + ptmr->OSTmrNext = (void *)0; + ptmr->OSTmrPrev = (void *)0; + pspoke->OSTmrEntries--; +} +#endif + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER MANAGEMENT TASK +* +* Description: This task is created by OSTmrInit(). +* +* Arguments : none +* +* Returns : none +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +static void OSTmr_Task (void *p_arg) +{ + INT8U err; + OS_TMR *ptmr; + OS_TMR *ptmr_next; + OS_TMR_CALLBACK pfnct; + OS_TMR_WHEEL *pspoke; + INT16U spoke; + + + p_arg = p_arg; /* Prevent compiler warning for not using 'p_arg' */ + for (;;) { + OSSemPend(OSTmrSemSignal, 0u, &err); /* Wait for signal indicating time to update timers */ + OSSchedLock(); + OSTmrTime++; /* Increment the current time */ + spoke = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE); /* Position on current timer wheel entry */ + pspoke = &OSTmrWheelTbl[spoke]; + ptmr = pspoke->OSTmrFirst; + while (ptmr != (OS_TMR *)0) { + ptmr_next = (OS_TMR *)ptmr->OSTmrNext; /* Point to next timer to update because current ... */ + /* ... timer could get unlinked from the wheel. */ + if (OSTmrTime == ptmr->OSTmrMatch) { /* Process each timer that expires */ + OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ + if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) { + OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC); /* Recalculate new position of timer in wheel */ + } else { + ptmr->OSTmrState = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */ + } + pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */ + if (pfnct != (OS_TMR_CALLBACK)0) { + (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); + } + } + ptmr = ptmr_next; + } + OSSchedUnlock(); + } +} +#endif + diff --git a/UCOS/CORE/ucos_ii.c b/UCOS/CORE/ucos_ii.c new file mode 100644 index 0000000..01b1227 --- /dev/null +++ b/UCOS/CORE/ucos_ii.c @@ -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 + + +#define OS_MASTER_FILE /* Prevent the following files from including includes.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + diff --git a/UCOS/CORE/ucos_ii.h b/UCOS/CORE/ucos_ii.h new file mode 100644 index 0000000..32ae220 --- /dev/null +++ b/UCOS/CORE/ucos_ii.h @@ -0,0 +1,1896 @@ +/* +********************************************************************************************************* +* uC/OS-II +* The Real-Time Kernel +* +* (c) Copyright 1992-2009, Micrium, Weston, FL +* All Rights Reserved +* +* File : uCOS_II.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_uCOS_II_H +#define OS_uCOS_II_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* +********************************************************************************************************* +* uC/OS-II VERSION NUMBER +********************************************************************************************************* +*/ + +#define OS_VERSION 291u /* Version of uC/OS-II (Vx.yy mult. by 100) */ + +/* +********************************************************************************************************* +* INCLUDE HEADER FILES +********************************************************************************************************* +*/ + +//#include +#include "includes.h" +#include +#include + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifdef OS_GLOBALS +#define OS_EXT +#else +#define OS_EXT extern +#endif + +#ifndef OS_FALSE +#define OS_FALSE 0u +#endif + +#ifndef OS_TRUE +#define OS_TRUE 1u +#endif + +#define OS_ASCII_NUL (INT8U)0 + +#define OS_PRIO_SELF 0xFFu /* Indicate SELF priority */ + +#if OS_TASK_STAT_EN > 0u +#define OS_N_SYS_TASKS 2u /* Number of system tasks */ +#else +#define OS_N_SYS_TASKS 1u +#endif + +#define OS_TASK_STAT_PRIO (OS_LOWEST_PRIO - 1u) /* Statistic task priority */ +#define OS_TASK_IDLE_PRIO (OS_LOWEST_PRIO) /* IDLE task priority */ + +#if OS_LOWEST_PRIO <= 63u +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 8u + 1u) /* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 8u + 1u) /* Size of ready table */ +#else +#define OS_EVENT_TBL_SIZE ((OS_LOWEST_PRIO) / 16u + 1u)/* Size of event table */ +#define OS_RDY_TBL_SIZE ((OS_LOWEST_PRIO) / 16u + 1u)/* Size of ready table */ +#endif + +#define OS_TASK_IDLE_ID 65535u /* ID numbers for Idle, Stat and Timer tasks */ +#define OS_TASK_STAT_ID 65534u +#define OS_TASK_TMR_ID 65533u + +#define OS_EVENT_EN (((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) || (OS_SEM_EN > 0u) || (OS_MUTEX_EN > 0u)) + +#define OS_TCB_RESERVED ((OS_TCB *)1) + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK STATUS (Bit definition for OSTCBStat) +********************************************************************************************************* +*/ +#define OS_STAT_RDY 0x00u /* Ready to run */ +#define OS_STAT_SEM 0x01u /* Pending on semaphore */ +#define OS_STAT_MBOX 0x02u /* Pending on mailbox */ +#define OS_STAT_Q 0x04u /* Pending on queue */ +#define OS_STAT_SUSPEND 0x08u /* Task is suspended */ +#define OS_STAT_MUTEX 0x10u /* Pending on mutual exclusion semaphore */ +#define OS_STAT_FLAG 0x20u /* Pending on event flag group */ +#define OS_STAT_MULTI 0x80u /* Pending on multiple events */ + +#define OS_STAT_PEND_ANY (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_FLAG) + +/* +********************************************************************************************************* +* TASK PEND STATUS (Status codes for OSTCBStatPend) +********************************************************************************************************* +*/ +#define OS_STAT_PEND_OK 0u /* Pending status OK, not pending, or pending complete */ +#define OS_STAT_PEND_TO 1u /* Pending timed out */ +#define OS_STAT_PEND_ABORT 2u /* Pending aborted */ + +/* +********************************************************************************************************* +* OS_EVENT types +********************************************************************************************************* +*/ +#define OS_EVENT_TYPE_UNUSED 0u +#define OS_EVENT_TYPE_MBOX 1u +#define OS_EVENT_TYPE_Q 2u +#define OS_EVENT_TYPE_SEM 3u +#define OS_EVENT_TYPE_MUTEX 4u +#define OS_EVENT_TYPE_FLAG 5u + +#define OS_TMR_TYPE 100u /* Used to identify Timers ... */ + /* ... (Must be different value than OS_EVENT_TYPE_xxx) */ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ +#define OS_FLAG_WAIT_CLR_ALL 0u /* Wait for ALL the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_AND 0u + +#define OS_FLAG_WAIT_CLR_ANY 1u /* Wait for ANY of the bits specified to be CLR (i.e. 0) */ +#define OS_FLAG_WAIT_CLR_OR 1u + +#define OS_FLAG_WAIT_SET_ALL 2u /* Wait for ALL the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_AND 2u + +#define OS_FLAG_WAIT_SET_ANY 3u /* Wait for ANY of the bits specified to be SET (i.e. 1) */ +#define OS_FLAG_WAIT_SET_OR 3u + + +#define OS_FLAG_CONSUME 0x80u /* Consume the flags if condition(s) satisfied */ + + +#define OS_FLAG_CLR 0u +#define OS_FLAG_SET 1u + +/* +********************************************************************************************************* +* Values for OSTickStepState +* +* Note(s): This feature is used by uC/OS-View. +********************************************************************************************************* +*/ + +#if OS_TICK_STEP_EN > 0u +#define OS_TICK_STEP_DIS 0u /* Stepping is disabled, tick runs as mormal */ +#define OS_TICK_STEP_WAIT 1u /* Waiting for uC/OS-View to set OSTickStepState to _ONCE */ +#define OS_TICK_STEP_ONCE 2u /* Process tick once and wait for next cmd from uC/OS-View */ +#endif + +/* +********************************************************************************************************* +* Possible values for 'opt' argument of OSSemDel(), OSMboxDel(), OSQDel() and OSMutexDel() +********************************************************************************************************* +*/ +#define OS_DEL_NO_PEND 0u +#define OS_DEL_ALWAYS 1u + +/* +********************************************************************************************************* +* OS???Pend() OPTIONS +* +* These #defines are used to establish the options for OS???PendAbort(). +********************************************************************************************************* +*/ +#define OS_PEND_OPT_NONE 0u /* NO option selected */ +#define OS_PEND_OPT_BROADCAST 1u /* Broadcast action to ALL tasks waiting */ + +/* +********************************************************************************************************* +* OS???PostOpt() OPTIONS +* +* These #defines are used to establish the options for OSMboxPostOpt() and OSQPostOpt(). +********************************************************************************************************* +*/ +#define OS_POST_OPT_NONE 0x00u /* NO option selected */ +#define OS_POST_OPT_BROADCAST 0x01u /* Broadcast message to ALL tasks waiting */ +#define OS_POST_OPT_FRONT 0x02u /* Post to highest priority task waiting */ +#define OS_POST_OPT_NO_SCHED 0x04u /* Do not call the scheduler if this option is selected */ + +/* +********************************************************************************************************* +* TASK OPTIONS (see OSTaskCreateExt()) +********************************************************************************************************* +*/ +#define OS_TASK_OPT_NONE 0x0000u /* NO option selected */ +#define OS_TASK_OPT_STK_CHK 0x0001u /* Enable stack checking for the task */ +#define OS_TASK_OPT_STK_CLR 0x0002u /* Clear the stack when the task is create */ +#define OS_TASK_OPT_SAVE_FP 0x0004u /* Save the contents of any floating-point registers */ + +/* +********************************************************************************************************* +* TIMER OPTIONS (see OSTmrStart() and OSTmrStop()) +********************************************************************************************************* +*/ +#define OS_TMR_OPT_NONE 0u /* No option selected */ + +#define OS_TMR_OPT_ONE_SHOT 1u /* Timer will not automatically restart when it expires */ +#define OS_TMR_OPT_PERIODIC 2u /* Timer will automatically restart when it expires */ + +#define OS_TMR_OPT_CALLBACK 3u /* OSTmrStop() option to call 'callback' w/ timer arg. */ +#define OS_TMR_OPT_CALLBACK_ARG 4u /* OSTmrStop() option to call 'callback' w/ new arg. */ + +/* +********************************************************************************************************* +* TIMER STATES +********************************************************************************************************* +*/ +#define OS_TMR_STATE_UNUSED 0u +#define OS_TMR_STATE_STOPPED 1u +#define OS_TMR_STATE_COMPLETED 2u +#define OS_TMR_STATE_RUNNING 3u + +/* +********************************************************************************************************* +* ERROR CODES +********************************************************************************************************* +*/ +#define OS_ERR_NONE 0u + +#define OS_ERR_EVENT_TYPE 1u +#define OS_ERR_PEND_ISR 2u +#define OS_ERR_POST_NULL_PTR 3u +#define OS_ERR_PEVENT_NULL 4u +#define OS_ERR_POST_ISR 5u +#define OS_ERR_QUERY_ISR 6u +#define OS_ERR_INVALID_OPT 7u +#define OS_ERR_ID_INVALID 8u +#define OS_ERR_PDATA_NULL 9u + +#define OS_ERR_TIMEOUT 10u +#define OS_ERR_EVENT_NAME_TOO_LONG 11u +#define OS_ERR_PNAME_NULL 12u +#define OS_ERR_PEND_LOCKED 13u +#define OS_ERR_PEND_ABORT 14u +#define OS_ERR_DEL_ISR 15u +#define OS_ERR_CREATE_ISR 16u +#define OS_ERR_NAME_GET_ISR 17u +#define OS_ERR_NAME_SET_ISR 18u +#define OS_ERR_ILLEGAL_CREATE_RUN_TIME 19u + +#define OS_ERR_MBOX_FULL 20u + +#define OS_ERR_Q_FULL 30u +#define OS_ERR_Q_EMPTY 31u + +#define OS_ERR_PRIO_EXIST 40u +#define OS_ERR_PRIO 41u +#define OS_ERR_PRIO_INVALID 42u + +#define OS_ERR_SCHED_LOCKED 50u +#define OS_ERR_SEM_OVF 51u + +#define OS_ERR_TASK_CREATE_ISR 60u +#define OS_ERR_TASK_DEL 61u +#define OS_ERR_TASK_DEL_IDLE 62u +#define OS_ERR_TASK_DEL_REQ 63u +#define OS_ERR_TASK_DEL_ISR 64u +#define OS_ERR_TASK_NAME_TOO_LONG 65u +#define OS_ERR_TASK_NO_MORE_TCB 66u +#define OS_ERR_TASK_NOT_EXIST 67u +#define OS_ERR_TASK_NOT_SUSPENDED 68u +#define OS_ERR_TASK_OPT 69u +#define OS_ERR_TASK_RESUME_PRIO 70u +#define OS_ERR_TASK_SUSPEND_IDLE 71u +#define OS_ERR_TASK_SUSPEND_PRIO 72u +#define OS_ERR_TASK_WAITING 73u + +#define OS_ERR_TIME_NOT_DLY 80u +#define OS_ERR_TIME_INVALID_MINUTES 81u +#define OS_ERR_TIME_INVALID_SECONDS 82u +#define OS_ERR_TIME_INVALID_MS 83u +#define OS_ERR_TIME_ZERO_DLY 84u +#define OS_ERR_TIME_DLY_ISR 85u + +#define OS_ERR_MEM_INVALID_PART 90u +#define OS_ERR_MEM_INVALID_BLKS 91u +#define OS_ERR_MEM_INVALID_SIZE 92u +#define OS_ERR_MEM_NO_FREE_BLKS 93u +#define OS_ERR_MEM_FULL 94u +#define OS_ERR_MEM_INVALID_PBLK 95u +#define OS_ERR_MEM_INVALID_PMEM 96u +#define OS_ERR_MEM_INVALID_PDATA 97u +#define OS_ERR_MEM_INVALID_ADDR 98u +#define OS_ERR_MEM_NAME_TOO_LONG 99u + +#define OS_ERR_NOT_MUTEX_OWNER 100u + +#define OS_ERR_FLAG_INVALID_PGRP 110u +#define OS_ERR_FLAG_WAIT_TYPE 111u +#define OS_ERR_FLAG_NOT_RDY 112u +#define OS_ERR_FLAG_INVALID_OPT 113u +#define OS_ERR_FLAG_GRP_DEPLETED 114u +#define OS_ERR_FLAG_NAME_TOO_LONG 115u + +#define OS_ERR_PIP_LOWER 120u + +#define OS_ERR_TMR_INVALID_DLY 130u +#define OS_ERR_TMR_INVALID_PERIOD 131u +#define OS_ERR_TMR_INVALID_OPT 132u +#define OS_ERR_TMR_INVALID_NAME 133u +#define OS_ERR_TMR_NON_AVAIL 134u +#define OS_ERR_TMR_INACTIVE 135u +#define OS_ERR_TMR_INVALID_DEST 136u +#define OS_ERR_TMR_INVALID_TYPE 137u +#define OS_ERR_TMR_INVALID 138u +#define OS_ERR_TMR_ISR 139u +#define OS_ERR_TMR_NAME_TOO_LONG 140u +#define OS_ERR_TMR_INVALID_STATE 141u +#define OS_ERR_TMR_STOPPED 142u +#define OS_ERR_TMR_NO_CALLBACK 143u + +/*$PAGE*/ +/* +********************************************************************************************************* +* EVENT CONTROL BLOCK +********************************************************************************************************* +*/ + +#if OS_LOWEST_PRIO <= 63u +typedef INT8U OS_PRIO; +#else +typedef INT16U OS_PRIO; +#endif + +#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u) +typedef struct os_event { + INT8U OSEventType; /* Type of event control block (see OS_EVENT_TYPE_xxxx) */ + void *OSEventPtr; /* Pointer to message or queue structure */ + INT16U OSEventCnt; /* Semaphore Count (not used if other EVENT type) */ + OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + +#if OS_EVENT_NAME_EN > 0u + INT8U *OSEventName; +#endif +} OS_EVENT; +#endif + + +/* +********************************************************************************************************* +* EVENT FLAGS CONTROL BLOCK +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) + +#if OS_FLAGS_NBITS == 8u /* Determine the size of OS_FLAGS (8, 16 or 32 bits) */ +typedef INT8U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 16u +typedef INT16U OS_FLAGS; +#endif + +#if OS_FLAGS_NBITS == 32u +typedef INT32U OS_FLAGS; +#endif + + +typedef struct os_flag_grp { /* Event Flag Group */ + INT8U OSFlagType; /* Should be set to OS_EVENT_TYPE_FLAG */ + void *OSFlagWaitList; /* Pointer to first NODE of task waiting on event flag */ + OS_FLAGS OSFlagFlags; /* 8, 16 or 32 bit flags */ +#if OS_FLAG_NAME_EN > 0u + INT8U *OSFlagName; +#endif +} OS_FLAG_GRP; + + + +typedef struct os_flag_node { /* Event Flag Wait List Node */ + void *OSFlagNodeNext; /* Pointer to next NODE in wait list */ + void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */ + void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */ + void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */ + OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */ + INT8U OSFlagNodeWaitType; /* Type of wait: */ + /* OS_FLAG_WAIT_AND */ + /* OS_FLAG_WAIT_ALL */ + /* OS_FLAG_WAIT_OR */ + /* OS_FLAG_WAIT_ANY */ +} OS_FLAG_NODE; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE MAILBOX DATA +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0u +typedef struct os_mbox_data { + void *OSMsg; /* Pointer to message in mailbox */ + OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +} OS_MBOX_DATA; +#endif + +/* +********************************************************************************************************* +* MEMORY PARTITION DATA STRUCTURES +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) +typedef struct os_mem { /* MEMORY CONTROL BLOCK */ + void *OSMemAddr; /* Pointer to beginning of memory partition */ + void *OSMemFreeList; /* Pointer to list of free memory blocks */ + INT32U OSMemBlkSize; /* Size (in bytes) of each block of memory */ + INT32U OSMemNBlks; /* Total number of blocks in this partition */ + INT32U OSMemNFree; /* Number of memory blocks remaining in this partition */ +#if OS_MEM_NAME_EN > 0u + INT8U *OSMemName; /* Memory partition name */ +#endif +} OS_MEM; + + +typedef struct os_mem_data { + void *OSAddr; /* Pointer to the beginning address of the memory partition */ + void *OSFreeList; /* Pointer to the beginning of the free list of memory blocks */ + INT32U OSBlkSize; /* Size (in bytes) of each memory block */ + INT32U OSNBlks; /* Total number of blocks in the partition */ + INT32U OSNFree; /* Number of memory blocks free */ + INT32U OSNUsed; /* Number of memory blocks used */ +} OS_MEM_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0u +typedef struct os_mutex_data { + OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ + BOOLEAN OSValue; /* Mutex value (OS_FALSE = used, OS_TRUE = available) */ + INT8U OSOwnerPrio; /* Mutex owner's task priority or 0xFF if no owner */ + INT8U OSMutexPIP; /* Priority Inheritance Priority or 0xFF if no owner */ +} OS_MUTEX_DATA; +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUE DATA +********************************************************************************************************* +*/ + +#if OS_Q_EN > 0u +typedef struct os_q { /* QUEUE CONTROL BLOCK */ + struct os_q *OSQPtr; /* Link to next queue control block in list of free blocks */ + void **OSQStart; /* Pointer to start of queue data */ + void **OSQEnd; /* Pointer to end of queue data */ + void **OSQIn; /* Pointer to where next message will be inserted in the Q */ + void **OSQOut; /* Pointer to where next message will be extracted from the Q */ + INT16U OSQSize; /* Size of queue (maximum number of entries) */ + INT16U OSQEntries; /* Current number of entries in the queue */ +} OS_Q; + + +typedef struct os_q_data { + void *OSMsg; /* Pointer to next message to be extracted from queue */ + INT16U OSNMsgs; /* Number of messages in message queue */ + INT16U OSQSize; /* Size of message queue */ + OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +} OS_Q_DATA; +#endif + +/* +********************************************************************************************************* +* SEMAPHORE DATA +********************************************************************************************************* +*/ + +#if OS_SEM_EN > 0u +typedef struct os_sem_data { + INT16U OSCnt; /* Semaphore count */ + OS_PRIO OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur */ + OS_PRIO OSEventGrp; /* Group corresponding to tasks waiting for event to occur */ +} OS_SEM_DATA; +#endif + +/* +********************************************************************************************************* +* TASK STACK DATA +********************************************************************************************************* +*/ + +#if OS_TASK_CREATE_EXT_EN > 0u +typedef struct os_stk_data { + INT32U OSFree; /* Number of free bytes on the stack */ + INT32U OSUsed; /* Number of bytes used on the stack */ +} OS_STK_DATA; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK CONTROL BLOCK +********************************************************************************************************* +*/ + +typedef struct os_tcb { + OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */ + +#if OS_TASK_CREATE_EXT_EN > 0u + void *OSTCBExtPtr; /* Pointer to user definable data for TCB extension */ + OS_STK *OSTCBStkBottom; /* Pointer to bottom of stack */ + INT32U OSTCBStkSize; /* Size of task stack (in number of stack elements) */ + INT16U OSTCBOpt; /* Task options as passed by OSTaskCreateExt() */ + INT16U OSTCBId; /* Task ID (0..65535) */ +#endif + + struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list */ + struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list */ + +#if (OS_EVENT_EN) + OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */ +#endif + +#if (OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u) + OS_EVENT **OSTCBEventMultiPtr; /* Pointer to multiple event control blocks */ +#endif + +#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) + void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost() */ +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) +#if OS_TASK_DEL_EN > 0u + OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */ +#endif + OS_FLAGS OSTCBFlagsRdy; /* Event flags that made task ready to run */ +#endif + + INT32U OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for event */ + INT8U OSTCBStat; /* Task status */ + INT8U OSTCBStatPend; /* Task PEND status */ + INT8U OSTCBPrio; /* Task priority (0 == highest) */ + + INT8U OSTCBX; /* Bit position in group corresponding to task priority */ + INT8U OSTCBY; /* Index into ready table corresponding to task priority */ + OS_PRIO OSTCBBitX; /* Bit mask to access bit position in ready table */ + OS_PRIO OSTCBBitY; /* Bit mask to access bit position in ready group */ + +#if OS_TASK_DEL_EN > 0u + INT8U OSTCBDelReq; /* Indicates whether a task needs to delete itself */ +#endif + +#if OS_TASK_PROFILE_EN > 0u + INT32U OSTCBCtxSwCtr; /* Number of time the task was switched in */ + INT32U OSTCBCyclesTot; /* Total number of clock cycles the task has been running */ + INT32U OSTCBCyclesStart; /* Snapshot of cycle counter at start of task resumption */ + OS_STK *OSTCBStkBase; /* Pointer to the beginning of the task stack */ + INT32U OSTCBStkUsed; /* Number of bytes used from the stack */ +#endif + +#if OS_TASK_NAME_EN > 0u + INT8U *OSTCBTaskName; +#endif + +#if OS_TASK_REG_TBL_SIZE > 0u + INT32U OSTCBRegTbl[OS_TASK_REG_TBL_SIZE]; +#endif +} OS_TCB; + +/*$PAGE*/ +/* +************************************************************************************************************************ +* TIMER DATA TYPES +************************************************************************************************************************ +*/ + +#if OS_TMR_EN > 0u +typedef void (*OS_TMR_CALLBACK)(void *ptmr, void *parg); + + + +typedef struct os_tmr { + INT8U OSTmrType; /* Should be set to OS_TMR_TYPE */ + OS_TMR_CALLBACK OSTmrCallback; /* Function to call when timer expires */ + void *OSTmrCallbackArg; /* Argument to pass to function when timer expires */ + void *OSTmrNext; /* Double link list pointers */ + void *OSTmrPrev; + INT32U OSTmrMatch; /* Timer expires when OSTmrTime == OSTmrMatch */ + INT32U OSTmrDly; /* Delay time before periodic update starts */ + INT32U OSTmrPeriod; /* Period to repeat timer */ +#if OS_TMR_CFG_NAME_EN > 0u + INT8U *OSTmrName; /* Name to give the timer */ +#endif + INT8U OSTmrOpt; /* Options (see OS_TMR_OPT_xxx) */ + INT8U OSTmrState; /* Indicates the state of the timer: */ + /* OS_TMR_STATE_UNUSED */ + /* OS_TMR_STATE_RUNNING */ + /* OS_TMR_STATE_STOPPED */ +} OS_TMR; + + + +typedef struct os_tmr_wheel { + OS_TMR *OSTmrFirst; /* Pointer to first timer in linked list */ + INT16U OSTmrEntries; +} OS_TMR_WHEEL; +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + +OS_EXT INT32U OSCtxSwCtr; /* Counter of number of context switches */ + +#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u) +OS_EXT OS_EVENT *OSEventFreeList; /* Pointer to list of free EVENT control blocks */ +OS_EXT OS_EVENT OSEventTbl[OS_MAX_EVENTS];/* Table of EVENT control blocks */ +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) +OS_EXT OS_FLAG_GRP OSFlagTbl[OS_MAX_FLAGS]; /* Table containing event flag groups */ +OS_EXT OS_FLAG_GRP *OSFlagFreeList; /* Pointer to free list of event flag groups */ +#endif + +#if OS_TASK_STAT_EN > 0u +OS_EXT INT8U OSCPUUsage; /* Percentage of CPU used */ +OS_EXT INT32U OSIdleCtrMax; /* Max. value that idle ctr can take in 1 sec. */ +OS_EXT INT32U OSIdleCtrRun; /* Val. reached by idle ctr at run time in 1 sec. */ +OS_EXT BOOLEAN OSStatRdy; /* Flag indicating that the statistic task is rdy */ +OS_EXT OS_STK OSTaskStatStk[OS_TASK_STAT_STK_SIZE]; /* Statistics task stack */ +#endif + +OS_EXT INT8U OSIntNesting; /* Interrupt nesting level */ + +OS_EXT INT8U OSLockNesting; /* Multitasking lock nesting level */ + +OS_EXT INT8U OSPrioCur; /* Priority of current task */ +OS_EXT INT8U OSPrioHighRdy; /* Priority of highest priority task */ + +OS_EXT OS_PRIO OSRdyGrp; /* Ready list group */ +OS_EXT OS_PRIO OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */ + +OS_EXT BOOLEAN OSRunning; /* Flag indicating that kernel is running */ + +OS_EXT INT8U OSTaskCtr; /* Number of tasks created */ + +OS_EXT volatile INT32U OSIdleCtr; /* Idle counter */ + +#ifdef OS_SAFETY_CRITICAL_IEC61508 +OS_EXT BOOLEAN OSSafetyCriticalStartFlag; +#endif + +OS_EXT OS_STK OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE]; /* Idle task stack */ + + +OS_EXT OS_TCB *OSTCBCur; /* Pointer to currently running TCB */ +OS_EXT OS_TCB *OSTCBFreeList; /* Pointer to list of free TCBs */ +OS_EXT OS_TCB *OSTCBHighRdy; /* Pointer to highest priority TCB R-to-R */ +OS_EXT OS_TCB *OSTCBList; /* Pointer to doubly linked list of TCBs */ +OS_EXT OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1u]; /* Table of pointers to created TCBs */ +OS_EXT OS_TCB OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]; /* Table of TCBs */ + +#if OS_TICK_STEP_EN > 0u +OS_EXT INT8U OSTickStepState; /* Indicates the state of the tick step feature */ +#endif + +#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) +OS_EXT OS_MEM *OSMemFreeList; /* Pointer to free list of memory partitions */ +OS_EXT OS_MEM OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager */ +#endif + +#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u) +OS_EXT OS_Q *OSQFreeList; /* Pointer to list of free QUEUE control blocks */ +OS_EXT OS_Q OSQTbl[OS_MAX_QS]; /* Table of QUEUE control blocks */ +#endif + +#if OS_TIME_GET_SET_EN > 0u +OS_EXT volatile INT32U OSTime; /* Current value of system time (in ticks) */ +#endif + +#if OS_TMR_EN > 0u +OS_EXT INT16U OSTmrFree; /* Number of free entries in the timer pool */ +OS_EXT INT16U OSTmrUsed; /* Number of timers used */ +OS_EXT INT32U OSTmrTime; /* Current timer time */ + +OS_EXT OS_EVENT *OSTmrSem; /* Sem. used to gain exclusive access to timers */ +OS_EXT OS_EVENT *OSTmrSemSignal; /* Sem. used to signal the update of timers */ + +OS_EXT OS_TMR OSTmrTbl[OS_TMR_CFG_MAX]; /* Table containing pool of timers */ +OS_EXT OS_TMR *OSTmrFreeList; /* Pointer to free list of timers */ +OS_EXT OS_STK OSTmrTaskStk[OS_TASK_TMR_STK_SIZE]; + +OS_EXT OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]; +#endif + +extern INT8U const OSUnMapTbl[256]; /* Priority->Index lookup table */ + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Independent Functions) +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#if (OS_EVENT_EN) + +#if (OS_EVENT_NAME_EN > 0u) +INT8U OSEventNameGet (OS_EVENT *pevent, + INT8U **pname, + INT8U *perr); + +void OSEventNameSet (OS_EVENT *pevent, + INT8U *pname, + INT8U *perr); +#endif + +#if (OS_EVENT_MULTI_EN > 0u) +INT16U OSEventPendMulti (OS_EVENT **pevents_pend, + OS_EVENT **pevents_rdy, + void **pmsgs_rdy, + INT32U timeout, + INT8U *perr); +#endif + +#endif + +/* +********************************************************************************************************* +* EVENT FLAGS MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) + +#if OS_FLAG_ACCEPT_EN > 0u +OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT8U *perr); +#endif + +OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, + INT8U *perr); + +#if OS_FLAG_DEL_EN > 0u +OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, + INT8U opt, + INT8U *perr); +#endif + +#if (OS_FLAG_EN > 0u) && (OS_FLAG_NAME_EN > 0u) +INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, + INT8U **pname, + INT8U *perr); + +void OSFlagNameSet (OS_FLAG_GRP *pgrp, + INT8U *pname, + INT8U *perr); +#endif + +OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U wait_type, + INT32U timeout, + INT8U *perr); + +OS_FLAGS OSFlagPendGetFlagsRdy (void); +OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, + OS_FLAGS flags, + INT8U opt, + INT8U *perr); + +#if OS_FLAG_QUERY_EN > 0u +OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, + INT8U *perr); +#endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOX MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MBOX_EN > 0u + +#if OS_MBOX_ACCEPT_EN > 0u +void *OSMboxAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSMboxCreate (void *pmsg); + +#if OS_MBOX_DEL_EN > 0u +OS_EVENT *OSMboxDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void *OSMboxPend (OS_EVENT *pevent, + INT32U timeout, + INT8U *perr); + +#if OS_MBOX_PEND_ABORT_EN > 0u +INT8U OSMboxPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_MBOX_POST_EN > 0u +INT8U OSMboxPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_MBOX_POST_OPT_EN > 0u +INT8U OSMboxPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_MBOX_QUERY_EN > 0u +INT8U OSMboxQuery (OS_EVENT *pevent, + OS_MBOX_DATA *p_mbox_data); +#endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) + +OS_MEM *OSMemCreate (void *addr, + INT32U nblks, + INT32U blksize, + INT8U *perr); + +void *OSMemGet (OS_MEM *pmem, + INT8U *perr); +#if OS_MEM_NAME_EN > 0u +INT8U OSMemNameGet (OS_MEM *pmem, + INT8U **pname, + INT8U *perr); + +void OSMemNameSet (OS_MEM *pmem, + INT8U *pname, + INT8U *perr); +#endif +INT8U OSMemPut (OS_MEM *pmem, + void *pblk); + +#if OS_MEM_QUERY_EN > 0u +INT8U OSMemQuery (OS_MEM *pmem, + OS_MEM_DATA *p_mem_data); +#endif + +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_MUTEX_EN > 0u + +#if OS_MUTEX_ACCEPT_EN > 0u +BOOLEAN OSMutexAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSMutexCreate (INT8U prio, + INT8U *perr); + +#if OS_MUTEX_DEL_EN > 0u +OS_EVENT *OSMutexDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSMutexPend (OS_EVENT *pevent, + INT32U timeout, + INT8U *perr); + +INT8U OSMutexPost (OS_EVENT *pevent); + +#if OS_MUTEX_QUERY_EN > 0u +INT8U OSMutexQuery (OS_EVENT *pevent, + OS_MUTEX_DATA *p_mutex_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* MESSAGE QUEUE MANAGEMENT +********************************************************************************************************* +*/ + +#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u) + +#if OS_Q_ACCEPT_EN > 0u +void *OSQAccept (OS_EVENT *pevent, + INT8U *perr); +#endif + +OS_EVENT *OSQCreate (void **start, + INT16U size); + +#if OS_Q_DEL_EN > 0u +OS_EVENT *OSQDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_FLUSH_EN > 0u +INT8U OSQFlush (OS_EVENT *pevent); +#endif + +void *OSQPend (OS_EVENT *pevent, + INT32U timeout, + INT8U *perr); + +#if OS_Q_PEND_ABORT_EN > 0u +INT8U OSQPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +#if OS_Q_POST_EN > 0u +INT8U OSQPost (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_FRONT_EN > 0u +INT8U OSQPostFront (OS_EVENT *pevent, + void *pmsg); +#endif + +#if OS_Q_POST_OPT_EN > 0u +INT8U OSQPostOpt (OS_EVENT *pevent, + void *pmsg, + INT8U opt); +#endif + +#if OS_Q_QUERY_EN > 0u +INT8U OSQQuery (OS_EVENT *pevent, + OS_Q_DATA *p_q_data); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* SEMAPHORE MANAGEMENT +********************************************************************************************************* +*/ +#if OS_SEM_EN > 0u + +#if OS_SEM_ACCEPT_EN > 0u +INT16U OSSemAccept (OS_EVENT *pevent); +#endif + +OS_EVENT *OSSemCreate (INT16U cnt); + +#if OS_SEM_DEL_EN > 0u +OS_EVENT *OSSemDel (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +void OSSemPend (OS_EVENT *pevent, + INT32U timeout, + INT8U *perr); + +#if OS_SEM_PEND_ABORT_EN > 0u +INT8U OSSemPendAbort (OS_EVENT *pevent, + INT8U opt, + INT8U *perr); +#endif + +INT8U OSSemPost (OS_EVENT *pevent); + +#if OS_SEM_QUERY_EN > 0u +INT8U OSSemQuery (OS_EVENT *pevent, + OS_SEM_DATA *p_sem_data); +#endif + +#if OS_SEM_SET_EN > 0u +void OSSemSet (OS_EVENT *pevent, + INT16U cnt, + INT8U *perr); +#endif + +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ +#if OS_TASK_CHANGE_PRIO_EN > 0u +INT8U OSTaskChangePrio (INT8U oldprio, + INT8U newprio); +#endif + +#if OS_TASK_CREATE_EN > 0u +INT8U OSTaskCreate (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio); +#endif + +#if OS_TASK_CREATE_EXT_EN > 0u +INT8U OSTaskCreateExt (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT8U prio, + INT16U id, + OS_STK *pbos, + INT32U stk_size, + void *pext, + INT16U opt); +#endif + +#if OS_TASK_DEL_EN > 0u +INT8U OSTaskDel (INT8U prio); +INT8U OSTaskDelReq (INT8U prio); +#endif + +#if OS_TASK_NAME_EN > 0u +INT8U OSTaskNameGet (INT8U prio, + INT8U **pname, + INT8U *perr); + +void OSTaskNameSet (INT8U prio, + INT8U *pname, + INT8U *perr); +#endif + +#if OS_TASK_SUSPEND_EN > 0u +INT8U OSTaskResume (INT8U prio); +INT8U OSTaskSuspend (INT8U prio); +#endif + +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +INT8U OSTaskStkChk (INT8U prio, + OS_STK_DATA *p_stk_data); +#endif + +#if OS_TASK_QUERY_EN > 0u +INT8U OSTaskQuery (INT8U prio, + OS_TCB *p_task_data); +#endif + + + +#if OS_TASK_REG_TBL_SIZE > 0u +INT32U OSTaskRegGet (INT8U prio, + INT8U id, + INT8U *perr); + +void OSTaskRegSet (INT8U prio, + INT8U id, + INT32U value, + INT8U *perr); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +void OSTimeDly (INT32U ticks); + +#if OS_TIME_DLY_HMSM_EN > 0u +INT8U OSTimeDlyHMSM (INT8U hours, + INT8U minutes, + INT8U seconds, + INT16U ms); +#endif + +#if OS_TIME_DLY_RESUME_EN > 0u +INT8U OSTimeDlyResume (INT8U prio); +#endif + +#if OS_TIME_GET_SET_EN > 0u +INT32U OSTimeGet (void); +void OSTimeSet (INT32U ticks); +#endif + +void OSTimeTick (void); + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#if OS_TMR_EN > 0u +OS_TMR *OSTmrCreate (INT32U dly, + INT32U period, + INT8U opt, + OS_TMR_CALLBACK callback, + void *callback_arg, + INT8U *pname, + INT8U *perr); + +BOOLEAN OSTmrDel (OS_TMR *ptmr, + INT8U *perr); + +#if OS_TMR_CFG_NAME_EN > 0u +INT8U OSTmrNameGet (OS_TMR *ptmr, + INT8U **pdest, + INT8U *perr); +#endif +INT32U OSTmrRemainGet (OS_TMR *ptmr, + INT8U *perr); + +INT8U OSTmrStateGet (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStart (OS_TMR *ptmr, + INT8U *perr); + +BOOLEAN OSTmrStop (OS_TMR *ptmr, + INT8U opt, + void *callback_arg, + INT8U *perr); + +INT8U OSTmrSignal (void); +#endif + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +void OSInit (void); + +void OSIntEnter (void); +void OSIntExit (void); + +#ifdef OS_SAFETY_CRITICAL_IEC61508 +void OSSafetyCriticalStart (void); +#endif + +#if OS_SCHED_LOCK_EN > 0u +void OSSchedLock (void); +void OSSchedUnlock (void); +#endif + +void OSStart (void); + +void OSStatInit (void); + +INT16U OSVersion (void); + +/*$PAGE*/ +/* +********************************************************************************************************* +* INTERNAL FUNCTION PROTOTYPES +* (Your application MUST NOT call these functions) +********************************************************************************************************* +*/ + +#if OS_TASK_DEL_EN > 0u +void OS_Dummy (void); +#endif + +#if (OS_EVENT_EN) +INT8U OS_EventTaskRdy (OS_EVENT *pevent, + void *pmsg, + INT8U msk, + INT8U pend_stat); + +void OS_EventTaskWait (OS_EVENT *pevent); + +void OS_EventTaskRemove (OS_TCB *ptcb, + OS_EVENT *pevent); + +#if (OS_EVENT_MULTI_EN > 0u) +void OS_EventTaskWaitMulti (OS_EVENT **pevents_wait); + +void OS_EventTaskRemoveMulti (OS_TCB *ptcb, + OS_EVENT **pevents_multi); +#endif + +void OS_EventWaitListInit (OS_EVENT *pevent); +#endif + +#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) +void OS_FlagInit (void); +void OS_FlagUnlink (OS_FLAG_NODE *pnode); +#endif + +void OS_MemClr (INT8U *pdest, + INT16U size); + +void OS_MemCopy (INT8U *pdest, + INT8U *psrc, + INT16U size); + +#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u) +void OS_MemInit (void); +#endif + +#if OS_Q_EN > 0u +void OS_QInit (void); +#endif + +void OS_Sched (void); + +#if (OS_EVENT_NAME_EN > 0u) || (OS_FLAG_NAME_EN > 0u) || (OS_MEM_NAME_EN > 0u) || (OS_TASK_NAME_EN > 0u) +INT8U OS_StrLen (INT8U *psrc); +#endif + +void OS_TaskIdle (void *p_arg); + +void OS_TaskReturn (void); + +#if OS_TASK_STAT_EN > 0u +void OS_TaskStat (void *p_arg); +#endif + +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +void OS_TaskStkClr (OS_STK *pbos, + INT32U size, + INT16U opt); +#endif + +#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u) +void OS_TaskStatStkChk (void); +#endif + +INT8U OS_TCBInit (INT8U prio, + OS_STK *ptos, + OS_STK *pbos, + INT16U id, + INT32U stk_size, + void *pext, + INT16U opt); + +#if OS_TMR_EN > 0u +void OSTmr_Init (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Target Specific Functions) +********************************************************************************************************* +*/ + +#if OS_DEBUG_EN > 0u +void OSDebugInit (void); +#endif + +void OSInitHookBegin (void); +void OSInitHookEnd (void); + +void OSTaskCreateHook (OS_TCB *ptcb); +void OSTaskDelHook (OS_TCB *ptcb); + +void OSTaskIdleHook (void); + +void OSTaskReturnHook (OS_TCB *ptcb); + +void OSTaskStatHook (void); +OS_STK *OSTaskStkInit (void (*task)(void *p_arg), + void *p_arg, + OS_STK *ptos, + INT16U opt); + +#if OS_TASK_SW_HOOK_EN > 0u +void OSTaskSwHook (void); +#endif + +void OSTCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0u +void OSTimeTickHook (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* (Application Specific Functions) +********************************************************************************************************* +*/ + +#if OS_APP_HOOKS_EN > 0u +void App_TaskCreateHook (OS_TCB *ptcb); +void App_TaskDelHook (OS_TCB *ptcb); +void App_TaskIdleHook (void); + +void App_TaskReturnHook (OS_TCB *ptcb); + +void App_TaskStatHook (void); + +#if OS_TASK_SW_HOOK_EN > 0u +void App_TaskSwHook (void); +#endif + +void App_TCBInitHook (OS_TCB *ptcb); + +#if OS_TIME_TICK_HOOK_EN > 0u +void App_TimeTickHook (void); +#endif +#endif + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +* +* IMPORTANT: These prototypes MUST be placed in OS_CPU.H +********************************************************************************************************* +*/ + +#if 0 +void OSStartHighRdy (void); +void OSIntCtxSw (void); +void OSCtxSw (void); +#endif + +/*$PAGE*/ +/* +********************************************************************************************************* +* LOOK FOR MISSING #define CONSTANTS +* +* This section is used to generate ERROR messages at compile time if certain #define constants are +* MISSING in OS_CFG.H. This allows you to quickly determine the source of the error. +* +* You SHOULD NOT change this section UNLESS you would like to add more comments as to the source of the +* compile time error. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* EVENT FLAGS +********************************************************************************************************* +*/ + +#ifndef OS_FLAG_EN +#error "OS_CFG.H, Missing OS_FLAG_EN: Enable (1) or Disable (0) code generation for Event Flags" +#else + #ifndef OS_MAX_FLAGS + #error "OS_CFG.H, Missing OS_MAX_FLAGS: Max. number of Event Flag Groups in your application" + #else + #if OS_MAX_FLAGS > 65500u + #error "OS_CFG.H, OS_MAX_FLAGS must be <= 65500" + #endif + #endif + + #ifndef OS_FLAGS_NBITS + #error "OS_CFG.H, Missing OS_FLAGS_NBITS: Determine #bits used for event flags, MUST be either 8, 16 or 32" + #endif + + #ifndef OS_FLAG_WAIT_CLR_EN + #error "OS_CFG.H, Missing OS_FLAG_WAIT_CLR_EN: Include code for Wait on Clear EVENT FLAGS" + #endif + + #ifndef OS_FLAG_ACCEPT_EN + #error "OS_CFG.H, Missing OS_FLAG_ACCEPT_EN: Include code for OSFlagAccept()" + #endif + + #ifndef OS_FLAG_DEL_EN + #error "OS_CFG.H, Missing OS_FLAG_DEL_EN: Include code for OSFlagDel()" + #endif + + #ifndef OS_FLAG_NAME_EN + #error "OS_CFG.H, Missing OS_FLAG_NAME_EN: Enable flag group names" + #endif + + #ifndef OS_FLAG_QUERY_EN + #error "OS_CFG.H, Missing OS_FLAG_QUERY_EN: Include code for OSFlagQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE MAILBOXES +********************************************************************************************************* +*/ + +#ifndef OS_MBOX_EN +#error "OS_CFG.H, Missing OS_MBOX_EN: Enable (1) or Disable (0) code generation for MAILBOXES" +#else + #ifndef OS_MBOX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MBOX_ACCEPT_EN: Include code for OSMboxAccept()" + #endif + + #ifndef OS_MBOX_DEL_EN + #error "OS_CFG.H, Missing OS_MBOX_DEL_EN: Include code for OSMboxDel()" + #endif + + #ifndef OS_MBOX_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_MBOX_PEND_ABORT_EN: Include code for OSMboxPendAbort()" + #endif + + #ifndef OS_MBOX_POST_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_EN: Include code for OSMboxPost()" + #endif + + #ifndef OS_MBOX_POST_OPT_EN + #error "OS_CFG.H, Missing OS_MBOX_POST_OPT_EN: Include code for OSMboxPostOpt()" + #endif + + #ifndef OS_MBOX_QUERY_EN + #error "OS_CFG.H, Missing OS_MBOX_QUERY_EN: Include code for OSMboxQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MEMORY MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MEM_EN +#error "OS_CFG.H, Missing OS_MEM_EN: Enable (1) or Disable (0) code generation for MEMORY MANAGER" +#else + #ifndef OS_MAX_MEM_PART + #error "OS_CFG.H, Missing OS_MAX_MEM_PART: Max. number of memory partitions" + #else + #if OS_MAX_MEM_PART > 65500u + #error "OS_CFG.H, OS_MAX_MEM_PART must be <= 65500" + #endif + #endif + + #ifndef OS_MEM_NAME_EN + #error "OS_CFG.H, Missing OS_MEM_NAME_EN: Enable memory partition names" + #endif + + #ifndef OS_MEM_QUERY_EN + #error "OS_CFG.H, Missing OS_MEM_QUERY_EN: Include code for OSMemQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MUTUAL EXCLUSION SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_MUTEX_EN +#error "OS_CFG.H, Missing OS_MUTEX_EN: Enable (1) or Disable (0) code generation for MUTEX" +#else + #ifndef OS_MUTEX_ACCEPT_EN + #error "OS_CFG.H, Missing OS_MUTEX_ACCEPT_EN: Include code for OSMutexAccept()" + #endif + + #ifndef OS_MUTEX_DEL_EN + #error "OS_CFG.H, Missing OS_MUTEX_DEL_EN: Include code for OSMutexDel()" + #endif + + #ifndef OS_MUTEX_QUERY_EN + #error "OS_CFG.H, Missing OS_MUTEX_QUERY_EN: Include code for OSMutexQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* MESSAGE QUEUES +********************************************************************************************************* +*/ + +#ifndef OS_Q_EN +#error "OS_CFG.H, Missing OS_Q_EN: Enable (1) or Disable (0) code generation for QUEUES" +#else + #ifndef OS_MAX_QS + #error "OS_CFG.H, Missing OS_MAX_QS: Max. number of queue control blocks" + #else + #if OS_MAX_QS > 65500u + #error "OS_CFG.H, OS_MAX_QS must be <= 65500" + #endif + #endif + + #ifndef OS_Q_ACCEPT_EN + #error "OS_CFG.H, Missing OS_Q_ACCEPT_EN: Include code for OSQAccept()" + #endif + + #ifndef OS_Q_DEL_EN + #error "OS_CFG.H, Missing OS_Q_DEL_EN: Include code for OSQDel()" + #endif + + #ifndef OS_Q_FLUSH_EN + #error "OS_CFG.H, Missing OS_Q_FLUSH_EN: Include code for OSQFlush()" + #endif + + #ifndef OS_Q_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_Q_PEND_ABORT_EN: Include code for OSQPendAbort()" + #endif + + #ifndef OS_Q_POST_EN + #error "OS_CFG.H, Missing OS_Q_POST_EN: Include code for OSQPost()" + #endif + + #ifndef OS_Q_POST_FRONT_EN + #error "OS_CFG.H, Missing OS_Q_POST_FRONT_EN: Include code for OSQPostFront()" + #endif + + #ifndef OS_Q_POST_OPT_EN + #error "OS_CFG.H, Missing OS_Q_POST_OPT_EN: Include code for OSQPostOpt()" + #endif + + #ifndef OS_Q_QUERY_EN + #error "OS_CFG.H, Missing OS_Q_QUERY_EN: Include code for OSQQuery()" + #endif +#endif + +/* +********************************************************************************************************* +* SEMAPHORES +********************************************************************************************************* +*/ + +#ifndef OS_SEM_EN +#error "OS_CFG.H, Missing OS_SEM_EN: Enable (1) or Disable (0) code generation for SEMAPHORES" +#else + #ifndef OS_SEM_ACCEPT_EN + #error "OS_CFG.H, Missing OS_SEM_ACCEPT_EN: Include code for OSSemAccept()" + #endif + + #ifndef OS_SEM_DEL_EN + #error "OS_CFG.H, Missing OS_SEM_DEL_EN: Include code for OSSemDel()" + #endif + + #ifndef OS_SEM_PEND_ABORT_EN + #error "OS_CFG.H, Missing OS_SEM_PEND_ABORT_EN: Include code for OSSemPendAbort()" + #endif + + #ifndef OS_SEM_QUERY_EN + #error "OS_CFG.H, Missing OS_SEM_QUERY_EN: Include code for OSSemQuery()" + #endif + + #ifndef OS_SEM_SET_EN + #error "OS_CFG.H, Missing OS_SEM_SET_EN: Include code for OSSemSet()" + #endif +#endif + +/* +********************************************************************************************************* +* TASK MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_MAX_TASKS +#error "OS_CFG.H, Missing OS_MAX_TASKS: Max. number of tasks in your application" +#else + #if OS_MAX_TASKS < 2u + #error "OS_CFG.H, OS_MAX_TASKS must be >= 2" + #endif + + #if OS_MAX_TASKS > ((OS_LOWEST_PRIO - OS_N_SYS_TASKS) + 1u) + #error "OS_CFG.H, OS_MAX_TASKS must be <= OS_LOWEST_PRIO - OS_N_SYS_TASKS + 1" + #endif + +#endif + +#if OS_LOWEST_PRIO > 254u +#error "OS_CFG.H, OS_LOWEST_PRIO must be <= 254 in V2.8x and higher" +#endif + +#ifndef OS_TASK_IDLE_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_IDLE_STK_SIZE: Idle task stack size" +#endif + +#ifndef OS_TASK_STAT_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_EN: Enable (1) or Disable(0) the statistics task" +#endif + +#ifndef OS_TASK_STAT_STK_SIZE +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_SIZE: Statistics task stack size" +#endif + +#ifndef OS_TASK_STAT_STK_CHK_EN +#error "OS_CFG.H, Missing OS_TASK_STAT_STK_CHK_EN: Check task stacks from statistics task" +#endif + +#ifndef OS_TASK_CHANGE_PRIO_EN +#error "OS_CFG.H, Missing OS_TASK_CHANGE_PRIO_EN: Include code for OSTaskChangePrio()" +#endif + +#ifndef OS_TASK_CREATE_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EN: Include code for OSTaskCreate()" +#endif + +#ifndef OS_TASK_CREATE_EXT_EN +#error "OS_CFG.H, Missing OS_TASK_CREATE_EXT_EN: Include code for OSTaskCreateExt()" +#endif + +#ifndef OS_TASK_DEL_EN +#error "OS_CFG.H, Missing OS_TASK_DEL_EN: Include code for OSTaskDel()" +#endif + +#ifndef OS_TASK_NAME_EN +#error "OS_CFG.H, Missing OS_TASK_NAME_EN: Enable task names" +#endif + +#ifndef OS_TASK_SUSPEND_EN +#error "OS_CFG.H, Missing OS_TASK_SUSPEND_EN: Include code for OSTaskSuspend() and OSTaskResume()" +#endif + +#ifndef OS_TASK_QUERY_EN +#error "OS_CFG.H, Missing OS_TASK_QUERY_EN: Include code for OSTaskQuery()" +#endif + +#ifndef OS_TASK_REG_TBL_SIZE +#error "OS_CFG.H, Missing OS_TASK_REG_TBL_SIZE: Include code for task specific registers" +#else + #if OS_TASK_REG_TBL_SIZE > 255u + #error "OS_CFG.H, OS_TASK_REG_TBL_SIZE must be <= 255" + #endif +#endif + +/* +********************************************************************************************************* +* TIME MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TICKS_PER_SEC +#error "OS_CFG.H, Missing OS_TICKS_PER_SEC: Sets the number of ticks in one second" +#endif + +#ifndef OS_TIME_DLY_HMSM_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_HMSM_EN: Include code for OSTimeDlyHMSM()" +#endif + +#ifndef OS_TIME_DLY_RESUME_EN +#error "OS_CFG.H, Missing OS_TIME_DLY_RESUME_EN: Include code for OSTimeDlyResume()" +#endif + +#ifndef OS_TIME_GET_SET_EN +#error "OS_CFG.H, Missing OS_TIME_GET_SET_EN: Include code for OSTimeGet() and OSTimeSet()" +#endif + +/* +********************************************************************************************************* +* TIMER MANAGEMENT +********************************************************************************************************* +*/ + +#ifndef OS_TMR_EN +#error "OS_CFG.H, Missing OS_TMR_EN: When (1) enables code generation for Timer Management" +#elif OS_TMR_EN > 0u + #if OS_SEM_EN == 0u + #error "OS_CFG.H, Semaphore management is required (set OS_SEM_EN to 1) when enabling Timer Management." + #error " Timer management require TWO semaphores." + #endif + + #ifndef OS_TMR_CFG_MAX + #error "OS_CFG.H, Missing OS_TMR_CFG_MAX: Determines the total number of timers in an application (2 .. 65500)" + #else + #if OS_TMR_CFG_MAX < 2u + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + + #if OS_TMR_CFG_MAX > 65500u + #error "OS_CFG.H, OS_TMR_CFG_MAX should be between 2 and 65500" + #endif + #endif + + #ifndef OS_TMR_CFG_WHEEL_SIZE + #error "OS_CFG.H, Missing OS_TMR_CFG_WHEEL_SIZE: Sets the size of the timer wheel (1 .. 1023)" + #else + #if OS_TMR_CFG_WHEEL_SIZE < 2u + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + + #if OS_TMR_CFG_WHEEL_SIZE > 1024u + #error "OS_CFG.H, OS_TMR_CFG_WHEEL_SIZE should be between 2 and 1024" + #endif + #endif + + #ifndef OS_TMR_CFG_NAME_EN + #error "OS_CFG.H, Missing OS_TMR_CFG_NAME_EN: Enable Timer names" + #endif + + #ifndef OS_TMR_CFG_TICKS_PER_SEC + #error "OS_CFG.H, Missing OS_TMR_CFG_TICKS_PER_SEC: Determines the rate at which tiem timer management task will run (Hz)" + #endif + + #ifndef OS_TASK_TMR_STK_SIZE + #error "OS_CFG.H, Missing OS_TASK_TMR_STK_SIZE: Determines the size of the Timer Task's stack" + #endif +#endif + + +/* +********************************************************************************************************* +* MISCELLANEOUS +********************************************************************************************************* +*/ + +#ifndef OS_ARG_CHK_EN +#error "OS_CFG.H, Missing OS_ARG_CHK_EN: Enable (1) or Disable (0) argument checking" +#endif + + +#ifndef OS_CPU_HOOKS_EN +#error "OS_CFG.H, Missing OS_CPU_HOOKS_EN: uC/OS-II hooks are found in the processor port files when 1" +#endif + + +#ifndef OS_APP_HOOKS_EN +#error "OS_CFG.H, Missing OS_APP_HOOKS_EN: Application-defined hooks are called from the uC/OS-II hooks" +#endif + + +#ifndef OS_DEBUG_EN +#error "OS_CFG.H, Missing OS_DEBUG_EN: Allows you to include variables for debugging or not" +#endif + + +#ifndef OS_LOWEST_PRIO +#error "OS_CFG.H, Missing OS_LOWEST_PRIO: Defines the lowest priority that can be assigned" +#endif + + +#ifndef OS_MAX_EVENTS +#error "OS_CFG.H, Missing OS_MAX_EVENTS: Max. number of event control blocks in your application" +#else + #if OS_MAX_EVENTS > 65500u + #error "OS_CFG.H, OS_MAX_EVENTS must be <= 65500" + #endif +#endif + + +#ifndef OS_SCHED_LOCK_EN +#error "OS_CFG.H, Missing OS_SCHED_LOCK_EN: Include code for OSSchedLock() and OSSchedUnlock()" +#endif + + +#ifndef OS_EVENT_MULTI_EN +#error "OS_CFG.H, Missing OS_EVENT_MULTI_EN: Include code for OSEventPendMulti()" +#endif + + +#ifndef OS_TASK_PROFILE_EN +#error "OS_CFG.H, Missing OS_TASK_PROFILE_EN: Include data structure for run-time task profiling" +#endif + + +#ifndef OS_TASK_SW_HOOK_EN +#error "OS_CFG.H, Missing OS_TASK_SW_HOOK_EN: Allows you to include the code for OSTaskSwHook() or not" +#endif + + +#ifndef OS_TICK_STEP_EN +#error "OS_CFG.H, Missing OS_TICK_STEP_EN: Allows to 'step' one tick at a time with uC/OS-View" +#endif + + +#ifndef OS_TIME_TICK_HOOK_EN +#error "OS_CFG.H, Missing OS_TIME_TICK_HOOK_EN: Allows you to include the code for OSTimeTickHook() or not" +#endif + +/* +********************************************************************************************************* +* SAFETY CRITICAL USE +********************************************************************************************************* +*/ + +#ifdef SAFETY_CRITICAL_RELEASE + +#if OS_ARG_CHK_EN < 1u +#error "OS_CFG.H, OS_ARG_CHK_EN must be enabled for safety-critical release code" +#endif + +#if OS_APP_HOOKS_EN > 0u +#error "OS_CFG.H, OS_APP_HOOKS_EN must be disabled for safety-critical release code" +#endif + +#if OS_DEBUG_EN > 0u +#error "OS_CFG.H, OS_DEBUG_EN must be disabled for safety-critical release code" +#endif + +#ifdef CANTATA +#error "OS_CFG.H, CANTATA must be disabled for safety-critical release code" +#endif + +#ifdef OS_SCHED_LOCK_EN +#error "OS_CFG.H, OS_SCHED_LOCK_EN must be disabled for safety-critical release code" +#endif + +#ifdef VSC_VALIDATION_MODE +#error "OS_CFG.H, VSC_VALIDATION_MODE must be disabled for safety-critical release code" +#endif + +#if OS_TASK_STAT_EN > 0u +#error "OS_CFG.H, OS_TASK_STAT_EN must be disabled for safety-critical release code" +#endif + +#if OS_TICK_STEP_EN > 0u +#error "OS_CFG.H, OS_TICK_STEP_EN must be disabled for safety-critical release code" +#endif + +#if OS_FLAG_EN > 0u + #if OS_FLAG_DEL_EN > 0 + #error "OS_CFG.H, OS_FLAG_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MBOX_EN > 0u + #if OS_MBOX_DEL_EN > 0u + #error "OS_CFG.H, OS_MBOX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_MUTEX_EN > 0u + #if OS_MUTEX_DEL_EN > 0u + #error "OS_CFG.H, OS_MUTEX_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_Q_EN > 0u + #if OS_Q_DEL_EN > 0u + #error "OS_CFG.H, OS_Q_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_SEM_EN > 0u + #if OS_SEM_DEL_EN > 0u + #error "OS_CFG.H, OS_SEM_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_TASK_EN > 0u + #if OS_TASK_DEL_EN > 0u + #error "OS_CFG.H, OS_TASK_DEL_EN must be disabled for safety-critical release code" + #endif +#endif + +#if OS_CRITICAL_METHOD != 3u +#error "OS_CPU.H, OS_CRITICAL_METHOD must be type 3 for safety-critical release code" +#endif + +#endif /* ------------------------ SAFETY_CRITICAL_RELEASE ------------------------ */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/UCOS/PORT/os_cpu.h b/UCOS/PORT/os_cpu.h new file mode 100644 index 0000000..db9db92 --- /dev/null +++ b/UCOS/PORT/os_cpu.h @@ -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 diff --git a/UCOS/PORT/os_cpu_a.asm b/UCOS/PORT/os_cpu_a.asm new file mode 100644 index 0000000..680cdf1 --- /dev/null +++ b/UCOS/PORT/os_cpu_a.asm @@ -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 diff --git a/UCOS/PORT/os_cpu_c.c b/UCOS/PORT/os_cpu_c.c new file mode 100644 index 0000000..302b274 --- /dev/null +++ b/UCOS/PORT/os_cpu_c.c @@ -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 +//#include + +/********************************************************************************************************* +* 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; +} +*/ \ No newline at end of file