/* USER CODE BEGIN Header /
/*
- @file : main.c
- @brief : Main program body
- @attention
- Copyright © 2024 STMicroelectronics.
- All rights reserved.
- This software is licensed under terms that can be found in the LICENSE file
- in the root directory of this software component.
- If no LICENSE file comes with this software, it is provided AS-IS.
/
/ USER CODE END Header /
/ Includes ------------------------------------------------------------------*/
#include “main.h”
/* Private includes ----------------------------------------------------------/
/ USER CODE BEGIN Includes */
#include <string.h>
#include “stm32f1xx_hal.h”
#include “btld.h”
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------/
/ USER CODE BEGIN PTD */
My_struct Rx_data;
My_struct Rx_M_data;
uint32_t Data_Length;
uint32_t Multiple_of_6;
uint32_t Remainder_of_6;
uint16_t App_crc;
uint32_t Data_Count;
bool Count_Flag = false;
uint8_t Err_CAN ;
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8];
uint32_t TxMailbox;
uint8_t G_loader_mode=0;
uint8_t G_flash_erase_CMD = 0;
uint8_t G_flash_pre_Program_CMD = 0;
uint8_t G_run_app_CMD=0;
uint8_t G_return_CRC_CMD=0;
uint8_t G_return_BOOT_CRC_CMD=0;
uint8_t G_end_flash_CMD=0;
uint8_t G_FlashInProgress=0;
uint32_t Sequence_Num = 0;
uint32_t Lastdata_Of_Arr = 0;
uint32_t test_count = 0;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------/
/ USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------/
/ USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/ USER CODE BEGIN PFP /
void send_confirm_msg(uint8_t status);
void Run_Application(void);
/ USER CODE END PFP */
/* Private user code ---------------------------------------------------------/
/ USER CODE BEGIN 0 /
void config_can_filter(void);
/ USER CODE END 0 */
/**
- @brief The application entry point.
- @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals /
MX_GPIO_Init();
MX_CAN_Init();
/ USER CODE BEGIN 2 */
config_can_filter();
/* USER CODE END 2 */
/* Infinite loop /
/ USER CODE BEGIN WHILE */
while (1)
{
/* Erase Flash */
if(G_flash_erase_CMD){
if(btld_EraseFlash()==HAL_OK){
/* Erase Success */
//Send CAN message to know we are in loader mode
TxHeader.ExtId= 0x1809FEC8;//TX_FEEDBACK_CANID + CANTX_SA;
TxHeader.IDE=CAN_ID_EXT;
TxHeader.RTR=CAN_RTR_DATA;
TxHeader.DLC=1;
TxData[0]=0xF0;
HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
}else{
/* Erase failed */
//Send CAN message to know we are in loader mode
TxHeader.ExtId = 0xff0055;//TX_FEEDBACK_CANID + CANTX_SA;
TxHeader.IDE=CAN_ID_EXT;
TxHeader.RTR=CAN_RTR_DATA;
TxHeader.DLC=1;
TxData[0]=0xFF;
HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
}
G_flash_erase_CMD=0;
}
if(G_flash_pre_Program_CMD == 1)
{
G_flash_pre_Program_CMD = 0;
btld_FlashBegin();
send_confirm_msg(0xff);
}
/* Run Application command */
if(G_run_app_CMD){
//btld_JumpToApp();
// Run_Application();
}
/* Calculate and send APPLICATION CRC */
if(G_return_CRC_CMD){
uint16_t checksum;
// if(Data_Length == btld_GetAppLength())
// {
checksum=btld_GetChecksum(Data_Length);//
if(App_crc == checksum)
{
TxHeader.ExtId = 0x1809FEC8;//
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 4;
TxData[0] = 0xF6;
TxData[1] = 0x00;//0xFF = Success, 0x00 = failed
TxData[2] = 0x00;//index & 0x00FF;
TxData[3] = 0x00;//(index & 0xFF00)>>8;
HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
}
// }
/* Send Available flash size for application */
G_return_CRC_CMD=0;
}
/* Calculate and send BOOTLOADER CRC */
if (G_return_BOOT_CRC_CMD) {
uint32_t checksum;
// checksum = btld_GetBootChecksum();
/* Send Achecksu, */
TxHeader.ExtId = 0xff0088;//TX_FEEDBACK_CANID + CANTX_SA;
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 5;
TxData[0] = 0x0F;
TxData[1] = (checksum & 0xFF000000) >> 24;
TxData[2] = (checksum & 0x00FF0000) >> 16;
TxData[3] = (checksum & 0x0000FF00) >> 8;
TxData[4] = (checksum & 0x000000FF);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
G_return_BOOT_CRC_CMD = 0;
}
/* End Falshing and respond success */
if (G_end_flash_CMD && G_FlashInProgress){
// btld_FlashEnd();
// btld_SaveAppLength();
// btld_SaveAppChecksum();
G_FlashInProgress=0;
G_end_flash_CMD=0;
// led_state = 1;
// request next WORD
/* Send success */
TxHeader.ExtId= 0xff0077;//TX_FEEDBACK_CANID + CANTX_SA;
TxHeader.IDE=CAN_ID_EXT;
TxHeader.RTR=CAN_RTR_DATA;
TxHeader.DLC=2;
TxData[0]=0xF7;
TxData[1]=0xFF; //Success
HAL_CAN_AddTxMessage(&hcan,&TxHeader,TxData,&TxMailbox);
}
if(Err_CAN == BL_CHKS_ERROR)
send_confirm_msg(0x00);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
- @brief System Clock Configuration
- @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
- in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV2;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
- @brief CAN Initialization Function
- @param None
- @retval None
*/
static void MX_CAN_Init(void)
{
/* USER CODE BEGIN CAN_Init 0 */
/* USER CODE END CAN_Init 0 */
/* USER CODE BEGIN CAN_Init 1 */
/* USER CODE END CAN_Init 1 /
hcan.Instance = CAN1;
hcan.Init.Prescaler = 18;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
/ USER CODE BEGIN CAN_Init 2 */
/* USER CODE END CAN_Init 2 */
}
/**
- @brief GPIO Initialization Function
- @param None
- @retval None
/
static void MX_GPIO_Init(void)
{
/ USER CODE BEGIN MX_GPIO_Init_1 /
/ USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 /
/ USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 /
/ config_can_filter ---------------------------------------------------------/
/ Setup Can-Filter /
/----------------------------------------------------------------------------*/
void config_can_filter(void){
CAN_FilterTypeDef sFilterConfig;
/* Leave mask bits for different messages commands
| */
uint32_t filterMask= RXFILTERMASK;
uint32_t filterID= RXFILTERID; // Only accept bootloader CAN message ID
/##-2- Configure the CAN Filter ###########################################/
//sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0;
sFilterConfig.FilterIdLow = 0;
sFilterConfig.FilterMaskIdHigh = 0;
sFilterConfig.FilterMaskIdLow = 0;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.FilterBank = 0;
// 配置过滤器
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)
{
}
// 使能FIFO接收到一个新报文中断
if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
}
}
/* HAL_CAN_RxCpltCallback ----------------------------------------------------/
/ Interrupt callback to manage Can Rx message ready to read /
/----------------------------------------------------------------------------/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef phcan)
{
CAN_RxHeaderTypeDef rxheader;
uint8_t data[8];
static uint16_t num = 0;
HAL_CAN_GetRxMessage(phcan,CAN_RX_FIFO0,&rxheader,data);
if (data[0]==0xF0){
G_loader_mode=1;
}
/* erease flash cmd ----------------------------------------------*/
if (rxheader.ExtId == CANID_S_B){
G_flash_erase_CMD=1;
}
/* run app cmd ----------------------------------------------*/
if (data[0]==0xF2 && G_loader_mode==1){
// if(btld_CheckForApplication()==BL_OK){
// G_run_app_CMD=1;
// }
}
/* ask bootloader crc cmd ----------------------------------------------*/
if (data[0]0x0F && G_loader_mode1){
G_return_BOOT_CRC_CMD=1;
}
/* ask for app crc cmd ----------------------------------------------*/
if (data[0]==0xF4 && G_loader_mode==1){
G_return_CRC_CMD=1;
}
/* start flash cmd ----------------------------------------------*/
if (data[0]==0xF5 && G_loader_mode==1){
// G_index=0;
// G_start_flash_CMD=1;
}
/* flash done cmd ----------------------------------------------*/
if (data[0]==0xF7 && G_loader_mode==1){
G_end_flash_CMD=1;
}
if(Count_Flag == true)
Data_Count ++;
if(rxheader.ExtId == CANID_UM_BF)//message base information
{
Count_Flag = true;
Data_Length = (uint32_t)data[5] | ((uint32_t)data[4] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[2] << 24);
Multiple_of_6 = Data_Length / 6;
Remainder_of_6 = Data_Length % 6;
App_crc = (uint16_t)data[7] | ((uint16_t)data[6] << 8);
G_flash_pre_Program_CMD = 1;
}
if(rxheader.ExtId == CANID_B_END)//end frame
{
int32_t jack = 0;
jack = (Data_Count - 1) * 6 - Data_Length;
if((jack > 6)||(jack < 0))
{
Data_Count = 0;
Data_Length = 0;
Count_Flag = false;
Err_CAN = BL_CHKS_ERROR;
}
}
/* next flash data cmd ----------------------------------------------*/
if(rxheader.ExtId == CANID_UM_DP)//data frame
{
uint64_t G_uint64_to_write = 0;
uint32_t G_uint32_to_write = 0;
uint16_t G_uint16_to_write = 0;
uint32_t index;
test_count++;
Sequence_Num = (data[0] << 8) | data[1];
G_uint32_to_write = (uint32_t) data[2]
| (((uint32_t) data[3]) << 8)| (((uint32_t) data[4]) << 16)
| (((uint32_t) data[5]) << 24) ;
G_uint16_to_write = (uint16_t) data[6]
| (((uint16_t) data[7]) << 8);
HAL_CAN_DeactivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
if(btld_FlashNext_32(G_uint32_to_write,&index) == BL_OK){
if(btld_FlashNext_16(G_uint16_to_write,&index) == BL_OK){
if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) == HAL_OK){
send_confirm_msg(0xff);
}
else
send_confirm_msg(0x01);
}
else
send_confirm_msg(0x00);
}
if(Sequence_Num == (Multiple_of_6 + 1)){//last frame
btld_FlashEnd();
G_return_CRC_CMD = 1;
}
#if 0
test_count++;
Sequence_Num = (data[0] << 8) | data[1];
if(Sequence_Num == (Multiple_of_6 + 1))
{
if(num < 170){
Rx_data.Remainder_Count = num;
Rx_data.Lastdata_Of_Arr = num * 6 + Remainder_of_6 -1;
memcpy(&Rx_data.buf[num*6],&data[2],6);
memset(&Rx_data.buf[(num+1)*6],0xff,1020-(num+1)*6);
Rx_data.Recv_Finish = true;
}
else{
Rx_M_data.r_count = num;
Rx_M_data.Lastdata_Of_Arr = (num-170) * 6 + Remainder_of_6;
memcpy(&Rx_M_data.buf[(num-170)*6],&data[2],6);
memset(&Rx_data.buf[(num-170+1)*6],0xff,1020-(num-170+1)*6);
Rx_M_data.Recv_Finish = true;
}
num = 0;
}
else
{
if(num < 170) // for 1020 bytes data
{
memcpy(&Rx_data.buf[num*6],&data[2],6);
if(num == 169)
{
Rx_data.r_count++;
Rx_data.Recv_Finish = true;
}
else
send_confirm_msg(0xff);
}
else if(num < 340)
{
memcpy(&Rx_M_data.buf[(num-170)*6],&data[2],6);
if(num == 339)
{
Rx_M_data.r_count ++;
Rx_M_data.Recv_Finish = true;
num = 0;
}
else
send_confirm_msg(0xff);
}
num++;
}
#endif
}
}
/* Run_Application -----------------------------------------------------------/
/ Bootloader is done. Prepare the mcu for application-Start and finaly Start /
/----------------------------------------------------------------------------*/
void Run_Application(void){
// HAL_TIM_Base_Stop_IT(&htim4);
// HAL_TIM_Base_DeInit(&htim4);
HAL_CAN_DeactivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
// HAL_CAN_Stop(&hcan);
HAL_CAN_DeInit(&hcan);
btld_JumpToApp();
}
/* send_confirm_msg ---------------------------------------------------------/
/ replay to can-massege /
/----------------------------------------------------------------------------*/
void send_confirm_msg(uint8_t status){
// uint16_t index;
// index = G_index/4;
TxHeader.ExtId = 0x1808FEC8;//0x00FE00 + CANTX_SA;
TxHeader.IDE = CAN_ID_EXT;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 4;
TxData[0] = 0xF6;
TxData[1] = status;//0xFF = Success, 0x00 = failed
TxData[2] = 0x00;//index & 0x00FF;
TxData[3] = 0x00;//(index & 0xFF00)>>8;
HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
}
/* USER CODE END 4 */
/**
- @brief This function is executed in case of error occurrence.
- @retval None
/
void Error_Handler(void)
{
/ USER CODE BEGIN Error_Handler_Debug /
/ User can add his own implementation to report the HAL error return state /
__disable_irq();
while (1)
{
}
/ USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
- @brief Reports the name of the source file and the source line number
-
where the assert_param error has occurred.
- @param file: pointer to the source file name
- @param line: assert_param error line source number
- @retval None
*/
void assert_failed(uint8_t file, uint32_t line)
{
/ USER CODE BEGIN 6 /
/ User can add his own implementation to report the file name and line number,
ex: printf(“Wrong parameters value: file %s on line %d\r\n”, file, line) /
/ USER CODE END 6 /
}
#endif / USE_FULL_ASSERT */