2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @addtogroup PIOS_SYS System Functions
6 * @brief PIOS System Initialization code
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
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
34 #ifdef PIOS_INCLUDE_SYS
36 /* Private Function Prototypes */
37 void NVIC_Configuration(void);
38 void SysTick_Handler(void);
41 #define MEM8(addr) (*((volatile uint8_t *)(addr)))
42 #define MEM16(addr) (*((volatile uint16_t *)(addr)))
43 #define MEM32(addr) (*((volatile uint32_t *)(addr)))
46 * Initialises all system peripherals
48 void PIOS_SYS_Init(void)
50 /* Setup STM32 system (RCC, clock, PLL and Flash configuration) - CMSIS Function */
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 */
63 /* Init the delay system */
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
|
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
|
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)
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 |
107 RCC_AHB3PeriphClockCmd(
108 // RCC_AHB3Periph_FSMC | No external static memory
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
|
136 RCC_APB2PeriphClockCmd(
137 RCC_APB2Periph_TIM1
|
138 RCC_APB2Periph_TIM8
|
139 RCC_APB2Periph_USART1
|
140 RCC_APB2Periph_USART6
|
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
|
154 * Configure all pins as input / pullup to avoid issues with
155 * uncommitted pins, excepting special-function pins that we need to
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
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
);
186 * Shutdown PIOS and reset the microcontroller:<BR>
188 * <LI>Disable all RTOS tasks
189 * <LI>Disable all interrupts
190 * <LI>Turn off all board LEDs
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();
203 // disable all interrupts
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? */
228 /* We will never reach this point */
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
)
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
);
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
)
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));
279 str
[i
] = ((b
> 9) ? ('A' - 10) : '0') + b
;
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
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 */
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 */