update credits
[librepilot.git] / flight / pios / stm32f4xx / pios_sys.c
blobc03297871c7d2efc29b8387c7770421bd9f9113d
1 /**
2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
4 * @{
5 * @addtogroup PIOS_SYS System Functions
6 * @brief PIOS System Initialization code
7 * @{
9 * @file pios_sys.c
10 * @author Michael Smith Copyright (C) 2011
11 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
12 * @brief Sets up basic STM32 system hardware, functions are called from Main.
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "pios.h"
34 #ifdef PIOS_INCLUDE_SYS
36 /* Private Function Prototypes */
37 void NVIC_Configuration(void);
38 void SysTick_Handler(void);
40 /* Local Macros */
41 #define MEM8(addr) (*((volatile uint8_t *)(addr)))
42 #define MEM16(addr) (*((volatile uint16_t *)(addr)))
43 #define MEM32(addr) (*((volatile uint32_t *)(addr)))
45 /**
46 * Initialises all system peripherals
48 void PIOS_SYS_Init(void)
50 /* Setup STM32 system (RCC, clock, PLL and Flash configuration) - CMSIS Function */
51 SystemInit();
52 SystemCoreClockUpdate(); /* update SystemCoreClock for use elsewhere */
55 * @todo might make sense to fetch the bus clocks and save them somewhere to avoid
56 * having to use the clunky get-all-clocks API everytime we need one.
59 /* Initialise Basic NVIC */
60 /* do this early to ensure that we take exceptions in the right place */
61 NVIC_Configuration();
63 /* Init the delay system */
64 PIOS_DELAY_Init();
67 * Turn on all the peripheral clocks.
68 * Micromanaging clocks makes no sense given the power situation in the system, so
69 * light up everything we might reasonably use here and just leave it on.
71 RCC_AHB1PeriphClockCmd(
72 RCC_AHB1Periph_GPIOA |
73 RCC_AHB1Periph_GPIOB |
74 RCC_AHB1Periph_GPIOC |
75 RCC_AHB1Periph_GPIOD |
76 RCC_AHB1Periph_GPIOE |
77 #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx)
78 RCC_AHB1Periph_GPIOF |
79 RCC_AHB1Periph_GPIOG |
80 RCC_AHB1Periph_GPIOH |
81 RCC_AHB1Periph_GPIOI |
82 #endif
83 RCC_AHB1Periph_CRC |
84 RCC_AHB1Periph_FLITF |
85 RCC_AHB1Periph_SRAM1 |
86 RCC_AHB1Periph_SRAM2 |
87 RCC_AHB1Periph_BKPSRAM |
88 #if defined(STM32F427_437xx) || defined(STM32F429_439xx)
89 RCC_AHB1Periph_SRAM3 |
90 #endif
91 RCC_AHB1Periph_DMA1 |
92 RCC_AHB1Periph_DMA2 |
93 // RCC_AHB1Periph_ETH_MAC | No ethernet
94 // RCC_AHB1Periph_ETH_MAC_Tx |
95 // RCC_AHB1Periph_ETH_MAC_Rx |
96 // RCC_AHB1Periph_ETH_MAC_PTP |
97 // RCC_AHB1Periph_OTG_HS | No high-speed USB (requires external PHY)
98 // RCC_AHB1Periph_OTG_HS_ULPI | No ULPI PHY (see above)
99 0, ENABLE);
100 RCC_AHB2PeriphClockCmd(
101 // RCC_AHB2Periph_DCMI | No camera @todo might make sense later for basic vision support?
102 // RCC_AHB2Periph_CRYP | No crypto
103 // RCC_AHB2Periph_HASH | No hash generator
104 // RCC_AHB2Periph_RNG | No random numbers @todo might be good to have later if entropy is desired
105 // RCC_AHB2Periph_OTG_FS |
106 0, ENABLE);
107 RCC_AHB3PeriphClockCmd(
108 // RCC_AHB3Periph_FSMC | No external static memory
109 0, ENABLE);
110 RCC_APB1PeriphClockCmd(
111 RCC_APB1Periph_TIM2 |
112 RCC_APB1Periph_TIM3 |
113 RCC_APB1Periph_TIM4 |
114 RCC_APB1Periph_TIM5 |
115 RCC_APB1Periph_TIM6 |
116 RCC_APB1Periph_TIM7 |
117 RCC_APB1Periph_TIM12 |
118 RCC_APB1Periph_TIM13 |
119 RCC_APB1Periph_TIM14 |
120 RCC_APB1Periph_WWDG |
121 RCC_APB1Periph_SPI2 |
122 RCC_APB1Periph_SPI3 |
123 RCC_APB1Periph_USART2 |
124 RCC_APB1Periph_USART3 |
125 RCC_APB1Periph_UART4 |
126 RCC_APB1Periph_UART5 |
127 RCC_APB1Periph_I2C1 |
128 RCC_APB1Periph_I2C2 |
129 RCC_APB1Periph_I2C3 |
130 RCC_APB1Periph_CAN1 |
131 RCC_APB1Periph_CAN2 |
132 RCC_APB1Periph_PWR |
133 RCC_APB1Periph_DAC |
134 0, ENABLE);
136 RCC_APB2PeriphClockCmd(
137 RCC_APB2Periph_TIM1 |
138 RCC_APB2Periph_TIM8 |
139 RCC_APB2Periph_USART1 |
140 RCC_APB2Periph_USART6 |
141 RCC_APB2Periph_ADC |
142 RCC_APB2Periph_ADC1 |
143 RCC_APB2Periph_ADC2 |
144 RCC_APB2Periph_ADC3 |
145 RCC_APB2Periph_SDIO |
146 RCC_APB2Periph_SPI1 |
147 RCC_APB2Periph_SYSCFG |
148 RCC_APB2Periph_TIM9 |
149 RCC_APB2Periph_TIM10 |
150 RCC_APB2Periph_TIM11 |
151 0, ENABLE);
154 * Configure all pins as input / pullup to avoid issues with
155 * uncommitted pins, excepting special-function pins that we need to
156 * remain as-is.
158 GPIO_InitTypeDef GPIO_InitStructure;
159 GPIO_StructInit(&GPIO_InitStructure);
160 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // default is un-pulled input
162 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
163 #if (PIOS_USB_ENABLED)
164 GPIO_InitStructure.GPIO_Pin &= ~(GPIO_Pin_11 | GPIO_Pin_12); // leave USB D+/D- alone
165 #endif
166 GPIO_InitStructure.GPIO_Pin &= ~(GPIO_Pin_13 | GPIO_Pin_14); // leave JTAG pins alone
167 GPIO_Init(GPIOA, &GPIO_InitStructure);
169 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
170 GPIO_Init(GPIOB, &GPIO_InitStructure);
172 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
173 GPIO_Init(GPIOC, &GPIO_InitStructure);
174 GPIO_Init(GPIOD, &GPIO_InitStructure);
175 GPIO_Init(GPIOE, &GPIO_InitStructure);
177 #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx)
178 GPIO_Init(GPIOF, &GPIO_InitStructure);
179 GPIO_Init(GPIOG, &GPIO_InitStructure);
180 GPIO_Init(GPIOH, &GPIO_InitStructure);
181 GPIO_Init(GPIOI, &GPIO_InitStructure);
182 #endif
186 * Shutdown PIOS and reset the microcontroller:<BR>
187 * <UL>
188 * <LI>Disable all RTOS tasks
189 * <LI>Disable all interrupts
190 * <LI>Turn off all board LEDs
191 * <LI>Reset STM32
192 * </UL>
193 * \return < 0 if reset failed
195 int32_t PIOS_SYS_Reset(void)
197 /* Disable all RTOS tasks */
198 #if defined(PIOS_INCLUDE_FREERTOS)
199 /* port specific FreeRTOS function to disable tasks (nested) */
200 portENTER_CRITICAL();
201 #endif
203 // disable all interrupts
204 PIOS_IRQ_Disable();
206 // turn off all board LEDs
207 #ifdef PIOS_INCLUDE_LED
208 # ifdef PIOS_LED_HEARTBEAT
209 PIOS_LED_Off(PIOS_LED_HEARTBEAT);
210 # endif /* PIOS_LED_HEARTBEAT */
211 # ifdef PIOS_LED_ALARM
212 PIOS_LED_Off(PIOS_LED_ALARM);
213 # endif /* PIOS_LED_ALARM */
214 # ifdef PIOS_BUZZER_ALARM
215 PIOS_LED_Off(PIOS_BUZZER_ALARM);
216 # endif /* PIOS_BUZZER_ALARM */
217 #endif /* PIOS_INCLUDE_LED */
219 /* XXX F10x port resets most (but not all) peripherals ... do we care? */
221 /* Reset STM32 */
222 NVIC_SystemReset();
224 while (1) {
228 /* We will never reach this point */
229 return -1;
233 * Returns the CPU's flash size (in bytes)
235 uint32_t PIOS_SYS_getCPUFlashSize(void)
237 return (uint32_t)MEM16(0x1fff7a22) * 1024; // it might be possible to locate in the OTP area, but haven't looked and not documented
241 * Returns the serial number as a string
242 * param[out] str pointer to a string which can store at least 32 digits + zero terminator!
243 * (24 digits returned for STM32)
244 * return < 0 if feature not supported
246 int32_t PIOS_SYS_SerialNumberGetBinary(uint8_t *array)
248 int i;
250 /* Stored in the so called "electronic signature" */
251 for (i = 0; i < PIOS_SYS_SERIAL_NUM_BINARY_LEN; ++i) {
252 uint8_t b = MEM8(0x1fff7a10 + i);
254 array[i] = b;
257 /* No error */
258 return 0;
262 * Returns the serial number as a string
263 * param[out] str pointer to a string which can store at least 32 digits + zero terminator!
264 * (24 digits returned for STM32)
265 * return < 0 if feature not supported
267 int32_t PIOS_SYS_SerialNumberGet(char *str)
269 int i;
271 /* Stored in the so called "electronic signature" */
272 for (i = 0; i < PIOS_SYS_SERIAL_NUM_ASCII_LEN; ++i) {
273 uint8_t b = MEM8(0x1fff7a10 + (i / 2));
274 if (!(i & 1)) {
275 b >>= 4;
277 b &= 0x0f;
279 str[i] = ((b > 9) ? ('A' - 10) : '0') + b;
281 str[i] = '\0';
283 /* No error */
284 return 0;
288 * Configures Vector Table base location and SysTick
290 void NVIC_Configuration(void)
292 /* Set the Vector Table base address as specified in .ld file */
293 extern void *pios_isr_vector_table_base;
295 NVIC_SetVectorTable((uint32_t)&pios_isr_vector_table_base, 0x0);
297 /* 4 bits for Interrupt priorities so no sub priorities */
298 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
300 /* Configure HCLK clock as SysTick clock source. */
301 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
304 #ifdef USE_FULL_ASSERT
306 * Reports the name of the source file and the source line number
307 * where the assert_param error has occurred.
308 * \param[in] file pointer to the source file name
309 * \param[in] line assert_param error line source number
310 * \retval None
312 void assert_failed(uint8_t *file, uint32_t line)
314 /* When serial debugging is implemented, use something like this. */
315 /* printf("Wrong parameters value: file %s on line %d\r\n", file, line); */
317 /* Setup the LEDs to Alternate */
318 #if defined(PIOS_LED_HEARTBEAT)
319 PIOS_LED_On(PIOS_LED_HEARTBEAT);
320 #endif /* PIOS_LED_HEARTBEAT */
321 #if defined(PIOS_LED_ALARM)
322 PIOS_LED_Off(PIOS_LED_ALARM);
323 #endif /* PIOS_LED_ALARM */
325 /* Infinite loop */
326 while (1) {
327 #if defined(PIOS_LED_HEARTBEAT)
328 PIOS_LED_Toggle(PIOS_LED_HEARTBEAT);
329 #endif /* PIOS_LED_HEARTBEAT */
330 #if defined(PIOS_LED_ALARM)
331 PIOS_LED_Toggle(PIOS_LED_ALARM);
332 #endif /* PIOS_LED_ALARM */
333 for (int i = 0; i < 1000000; i++) {
338 #endif /* ifdef USE_FULL_ASSERT */
340 #endif /* PIOS_INCLUDE_SYS */
343 * @}
344 * @}