1 /*
2 * Copyright (c) 2022 Talkweb Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <stdio.h>
16 #include "stm32f4xx_hal.h"
17
18 #define APP_START_ADDR (0x8010000)
19 #define JUMP_APP_ADDR (APP_START_ADDR + 4)
20 #define APP_RAM_CMP_VAL 0x2FFE0000
21 #define APP_RAM_CMP_ADDR 0x20020000
22 #define RCC_PLL_PLLM 16
23 #define RCC_PLL_PLLN 192
24 #define RCC_PLL_PLLQ 4
25
26 #define UART_BAUDRATE 115200
27
28 UART_HandleTypeDef huart1;
29
30 static void SystemClockConfig(void);
31 static void MX_USART1_UART_Init(void);
32 static void IapExecuteApp(unsigned int appStartAddr);
33
main(void)34 int main(void)
35 {
36 HAL_Init();
37 SystemClockConfig();
38 MX_USART1_UART_Init();
39 printf("stm32f4xx bootloader start...\r\n");
40 IapExecuteApp(APP_START_ADDR);
41 while (1) {
42 }
43 }
44
SystemClockConfig(void)45 static void SystemClockConfig(void)
46 {
47 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
48 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
49
50 __HAL_RCC_PWR_CLK_ENABLE();
51 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
52 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
53 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
54 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
55 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
56 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
57 RCC_OscInitStruct.PLL.PLLM = RCC_PLL_PLLM;
58 RCC_OscInitStruct.PLL.PLLN = RCC_PLL_PLLN;
59 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
60 RCC_OscInitStruct.PLL.PLLQ = RCC_PLL_PLLQ;
61 HAL_RCC_OscConfig(&RCC_OscInitStruct);
62
63 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
64 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
65 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
66 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
67 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
68 HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
69 }
70
MX_USART1_UART_Init(void)71 static void MX_USART1_UART_Init(void)
72 {
73 huart1.Instance = USART1;
74 huart1.Init.BaudRate = UART_BAUDRATE;
75 huart1.Init.WordLength = UART_WORDLENGTH_8B;
76 huart1.Init.StopBits = UART_STOPBITS_1;
77 huart1.Init.Parity = UART_PARITY_NONE;
78 huart1.Init.Mode = UART_MODE_TX_RX;
79 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
80 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
81 HAL_UART_Init(&huart1);
82 }
83
HAL_UART_MspInit(UART_HandleTypeDef * huart)84 void HAL_UART_MspInit(UART_HandleTypeDef *huart)
85 {
86 GPIO_InitTypeDef GPIO_InitStruct = {0};
87 if (huart->Instance == USART1) {
88 __HAL_RCC_USART1_CLK_ENABLE();
89 __HAL_RCC_GPIOB_CLK_ENABLE();
90
91 GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
92 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
93 GPIO_InitStruct.Pull = GPIO_NOPULL;
94 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
95 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
96 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
97 }
98 }
99
HAL_UART_MspDeInit(UART_HandleTypeDef * huart)100 void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
101 {
102 if (huart->Instance == USART1) {
103 __HAL_RCC_USART1_CLK_DISABLE();
104 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6 | GPIO_PIN_7);
105 }
106 }
107
108 typedef void (*pFunction)(void);
109 pFunction Jump_To_Application;
MSR_MSP(unsigned int ulAddr)110 static void MSR_MSP(unsigned int ulAddr)
111 {
112 __ASM volatile("MSR MSP, r0");
113 __ASM volatile("BX r14");
114 }
115
IapExecuteApp(unsigned int appStartAddr)116 static void IapExecuteApp(unsigned int appStartAddr)
117 {
118 unsigned int JumpAddress;
119
120 if (((*(volatile unsigned int *)appStartAddr) & APP_RAM_CMP_VAL) == APP_RAM_CMP_ADDR) {
121 JumpAddress = *(volatile unsigned int *)JUMP_APP_ADDR;
122 Jump_To_Application = (pFunction)JumpAddress;
123 MSR_MSP(*(volatile unsigned int *)appStartAddr);
124 HAL_UART_MspDeInit(&huart1);
125 HAL_RCC_DeInit();
126 Jump_To_Application();
127 }
128
129 printf("into app fail! \r\n");
130 }
131
_write(int fd,char * pBuffer,int size)132 int _write(int fd, char *pBuffer, int size)
133 {
134 for (int i = 0; i < size; i++) {
135 HAL_UART_Transmit(&huart1, (unsigned char *)&pBuffer[i], 1, 0xFFFF);
136 }
137 return size;
138 }
139