• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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