614 lines
17 KiB
C
614 lines
17 KiB
C
#include "bootloader.h"
|
||
#include "custom_receive_and_write.h"
|
||
|
||
extern FLASH_EraseInitTypeDef EraseInitStruct;
|
||
|
||
struct flag FLAGS;
|
||
struct Bootloader_Errors_Counters BOOTLOADER_ERRORS_COUNTERS;
|
||
struct Bootloader_Errors BOOTLOADER_ERRORS;
|
||
|
||
uint32_t app_current_add; // address for writing pages
|
||
int cnt_tim_reset = 0; // WD Tim counter
|
||
|
||
|
||
uint8_t ReceiveDataUART[4]; // buffer for CMD
|
||
uint8_t Data2Write[PAGE_SIZE*2]; // DMA buffer for application
|
||
uint8_t CAN_Data[8];
|
||
|
||
|
||
CAN_TxHeaderTypeDef TxHeader;
|
||
CAN_RxHeaderTypeDef RxHeader;
|
||
uint32_t TxMailBox = 0; // num of used mail
|
||
|
||
|
||
extern UART_HandleTypeDef huart_boot; // uart handler for boot uart
|
||
extern DMA_HandleTypeDef hdma_usart_boot_rx; // dma handler for boot uart
|
||
struct UARTSettings UARTSet; // settings for uart
|
||
|
||
void Bootloader_Init(void)
|
||
{
|
||
HAL_Init();
|
||
Boot_SystemClock_Config();
|
||
MX_DMA_Init();
|
||
//Если используется ЮСАРТ - инициализация
|
||
#ifdef __USART_H__
|
||
|
||
UARTSet.UARTx = UART_BOOT;
|
||
UARTSet.UART_Speed = UART_SPEED;
|
||
UARTSet.GPIOx = UART_PORT;
|
||
UARTSet.GPIO_PIN_RX = UART_PIN_RX;
|
||
UARTSet.GPIO_PIN_TX = UART_PIN_TX;
|
||
UARTSet.DMAChannel = DMA_UART_Channel;
|
||
|
||
User_UART_Init(&huart_boot, &hdma_usart_boot_rx, &UARTSet);
|
||
#endif
|
||
|
||
//Если используется SD-карта - инициализация
|
||
#ifdef __SDIO_H__
|
||
BSP_SD_ITConfig();
|
||
#endif
|
||
|
||
#ifdef __CAN_H__
|
||
MX_CAN_Init();
|
||
#endif
|
||
|
||
//Инициализация светодиодов
|
||
MX_GPIO_Init();
|
||
MX_TIM7_Init();
|
||
}
|
||
|
||
HAL_StatusTypeDef res_hal;
|
||
void Bootloader_main(void) // main function, that defines bootloader behaviour
|
||
{
|
||
/*
|
||
// Настройка доступной переферии с помощью define
|
||
Bootloader_Init();
|
||
*/
|
||
|
||
/* START APPLICATION */
|
||
if (ReadKey() == BL_KEY_APP_WRITTEN)
|
||
{
|
||
// jump to main app
|
||
//Задаётся адрес программы со смещением от начала вектора прерываний
|
||
uint32_t app_jump_adr;
|
||
app_jump_adr=*((volatile uint32_t*)(MAIN_APP_START_ADR+4));
|
||
void(*GoToApp)(void);
|
||
|
||
//Деинициализация HAL
|
||
HAL_DeInit();
|
||
|
||
GoToApp = (void (*) (void)) app_jump_adr;
|
||
//Перенос вектора прерываний на начало зашитой программы
|
||
__disable_irq();
|
||
__set_MSP(*((volatile uint32_t*)MAIN_APP_START_ADR));
|
||
__enable_irq();
|
||
//Переход к выполнению зашитой программы
|
||
GoToApp();
|
||
}
|
||
else /* START PROGRAMMING MCU */
|
||
{
|
||
/* MCU Configuration for bootloader-------------------------------------------*/
|
||
/* Reset of all peripherals, Initializes the Flash BootloaderCMD and the Systick. */
|
||
Bootloader_Init();
|
||
FLAGS.InitOrWait = 0;
|
||
|
||
// waif for commant for programming
|
||
do{
|
||
res_hal=HAL_UART_Receive_IT(&huart_boot, ReceiveDataUART, sizeof(ReceiveDataUART));
|
||
if(res_hal!=HAL_OK){
|
||
BOOTLOADER_ERRORS_COUNTERS.USART_RECEIVE++;
|
||
BOOTLOADER_ERRORS.USART_RECEIVE=1;
|
||
}
|
||
}while(res_hal!=HAL_OK); // if usart err - try start receive again
|
||
|
||
HAL_CAN_Start(&hcan);
|
||
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||
|
||
CAN_FilterTypeDef canFilterConfig;
|
||
canFilterConfig.FilterBank = 0;
|
||
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
|
||
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
|
||
canFilterConfig.FilterIdHigh = 0x0000;
|
||
canFilterConfig.FilterIdLow = 0x0000;
|
||
canFilterConfig.FilterMaskIdHigh = 0x0000;
|
||
canFilterConfig.FilterMaskIdLow = 0x0000;
|
||
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
|
||
canFilterConfig.FilterActivation = ENABLE;
|
||
canFilterConfig.SlaveStartFilterBank = 14;
|
||
HAL_CAN_ConfigFilter(&hcan, &canFilterConfig);
|
||
|
||
// FLAGS.StartInit=1;
|
||
// FLAGS.reInitMCU=1;
|
||
// FLAGS.BootloaderCMD = 2;
|
||
app_current_add = MAIN_APP_START_ADR;
|
||
// HAL_CAN_Start(&hcan);
|
||
/* Infinite loop */
|
||
while (1)
|
||
{
|
||
// HAL_Delay(10);
|
||
// HAL_UART_Transmit(&huart_boot, (uint8_t *)"000000", 6, HAL_MAX_DELAY);
|
||
|
||
// choose interface for programming
|
||
if (FLAGS.StartInit)
|
||
{
|
||
|
||
|
||
if (FLAGS.reInitMCU) // if its reInit request - erase outdate app
|
||
{
|
||
GPIOB->ODR^=0x2000;
|
||
res_hal=FLASH_Erase_App();
|
||
if(res_hal!=HAL_OK)
|
||
{
|
||
FLAGS.StartInit=1;
|
||
|
||
BOOTLOADER_ERRORS.FLASH_ERASE = 1;
|
||
continue;
|
||
}
|
||
BOOTLOADER_ERRORS.FLASH_ERASE = 0;
|
||
GPIOB->ODR^=0x2000;
|
||
FLAGS.reInitMCU = 0;
|
||
}
|
||
FLAGS.StartInit = 0;
|
||
|
||
HAL_UART_AbortReceive_IT(&huart_boot);
|
||
HAL_CAN_Stop(&hcan);
|
||
HAL_CAN_DeactivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||
|
||
switch ((int)FLAGS.BootloaderCMD)
|
||
{
|
||
// UART
|
||
#ifdef __USART_H__
|
||
case 1:/* UART */
|
||
FLAGS.InitBootPeriph = 1;
|
||
// start receiving app.bin
|
||
res_hal = HAL_UART_Receive_DMA(&huart_boot, Data2Write, PAGE_SIZE*2);
|
||
if(res_hal!=HAL_OK)
|
||
{
|
||
FLAGS.StartInit=1;
|
||
BOOTLOADER_ERRORS_COUNTERS.USART_RECEIVE++;
|
||
BOOTLOADER_ERRORS.USART_RECEIVE = 1;
|
||
break;
|
||
}
|
||
// code of writing app in flash in callbacks functions:
|
||
// HAL_UART_RxHalfCpltCallback and HAL_UART_RxCpltCallback
|
||
break;
|
||
#endif
|
||
|
||
#ifdef __CAN_H__
|
||
// CAN
|
||
case 2: /* CAN */
|
||
// activate can and start receiving app.bin
|
||
FLAGS.InitOrWait=1;
|
||
res_hal = HAL_CAN_Start(&hcan);
|
||
res_hal = HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE);
|
||
// code of writing app in flash in callback functions:
|
||
// HAL_CAN_RxFifo0MsgPendingCallback
|
||
break;
|
||
#endif
|
||
|
||
// SD
|
||
#ifdef __SDIO_H__
|
||
case 3: /* SD */
|
||
if (FLAGS.SDCardIn==0) // wait for sd-card
|
||
{
|
||
FLAGS.StartInit=1; // if there is no card, exit programmator and go in again
|
||
BOOTLOADER_ERRORS.SD_CARD_NOT_INSERTED = 1;
|
||
//Ошибка SD карты. Начать приём новой cmd
|
||
break;
|
||
}
|
||
HAL_Delay(100); // wait for inputting SD Card
|
||
if (FLAGS.SDCardIn==0)
|
||
{
|
||
FLAGS.StartInit=1;
|
||
BOOTLOADER_ERRORS.SD_CARD_NOT_INSERTED = 1;
|
||
break;
|
||
}
|
||
|
||
FRESULT res_fresult;
|
||
SD_Programming(&res_fresult, &res_hal); // programming from sd card
|
||
// res_fresual - status for sd card read // res_hal - status for flash write
|
||
//Если всё удачно - выполнить код ниже. Если нет - StartInit = 1, break
|
||
if(res_fresult!=FR_OK || res_hal!=HAL_OK)
|
||
{
|
||
FLAGS.StartInit=1;
|
||
|
||
if(res_fresult!=FR_OK){
|
||
BOOTLOADER_ERRORS_COUNTERS.SD_CARD_READ++;
|
||
BOOTLOADER_ERRORS.SD_CARD_READ = 1;
|
||
}
|
||
if(res_hal!=HAL_OK){
|
||
BOOTLOADER_ERRORS_COUNTERS.FLASH_WRITE++;
|
||
BOOTLOADER_ERRORS.FLASH_WRITE = 1;
|
||
}
|
||
break;
|
||
}
|
||
// write Key: application in Flash, and reset MCU
|
||
{
|
||
ResetKey();
|
||
SetKey();
|
||
NVIC_SystemReset();
|
||
}// reset mcu
|
||
break;
|
||
#endif
|
||
|
||
default: // if command is incorrect - wait CMD
|
||
BOOTLOADER_ERRORS_COUNTERS.CMD_INVALID++; // uncorrect command
|
||
BOOTLOADER_ERRORS.CMD_INVALID=1;
|
||
do
|
||
{
|
||
res_hal=HAL_UART_Receive_IT(&huart_boot, ReceiveDataUART, sizeof(ReceiveDataUART));
|
||
if(res_hal!=HAL_OK){
|
||
BOOTLOADER_ERRORS_COUNTERS.USART_RECEIVE++; // err when initialize uart
|
||
BOOTLOADER_ERRORS.USART_RECEIVE=1;}
|
||
}while(res_hal!=HAL_OK);
|
||
HAL_CAN_Start(&hcan);
|
||
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||
}
|
||
}
|
||
|
||
// TxHeader.StdId = 0x200; // ID OF MESSAGE
|
||
// TxHeader.ExtId = 0; // STANDART FRAME (NOT EXTENTED)
|
||
// TxHeader.RTR = CAN_RTR_DATA; // TRANSMIT DATA OR
|
||
// TxHeader.IDE = CAN_ID_STD; // STANDART FRAME
|
||
// TxHeader.DLC = 8; // DATA SIZE
|
||
// TxHeader.TransmitGlobalTime = DISABLE; //THIS MODE IS NOT USED, SO DISABLE
|
||
// uint8_t asd[8] = "ABCDEFGL";
|
||
// while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0); // wait for free mail box
|
||
// res_hal = HAL_CAN_AddTxMessage(&hcan, &TxHeader, asd, &TxMailBox); // add to mail for transmit
|
||
// HAL_Delay(1000);
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void SD_Programming(FRESULT *res_fresult, HAL_StatusTypeDef *res_hal)
|
||
{
|
||
// init peripth
|
||
MX_FATFS_Init();
|
||
MX_SDIO_SD_Init();
|
||
FIL MFile;
|
||
int SizeApp;
|
||
int AppCount;
|
||
|
||
// mount disk
|
||
uint8_t MOUNT=1;
|
||
*res_fresult = f_mount(&SDFatFS, (TCHAR const*)SDPath, 1);
|
||
if(*res_fresult != FR_OK) return;
|
||
|
||
// name of the application file
|
||
static char path[8] = "app.bin";
|
||
path[7] = '\0';
|
||
|
||
|
||
// OPEN AND READ
|
||
*res_fresult = f_open(&MFile, (const TCHAR*)path, FA_READ);
|
||
if (*res_fresult == FR_OK)
|
||
{
|
||
SizeApp = MFile.fsize;
|
||
AppCount = 0; // counter of written bytes
|
||
|
||
|
||
unsigned int bytesRead;
|
||
// reading and writing two pages
|
||
while(SizeApp - AppCount >= PAGE_SIZE*2) // read while count of rest bytes more than size of two pages
|
||
{
|
||
*res_fresult = f_read(&MFile, Data2Write, PAGE_SIZE*2, &bytesRead);
|
||
|
||
if(*res_fresult != FR_OK) return;
|
||
|
||
AppCount += PAGE_SIZE*2;
|
||
|
||
*res_hal = FLASH_Write_Page(&app_current_add, Data2Write, PAGE_SIZE*2);
|
||
|
||
if(*res_hal != HAL_OK) return;
|
||
|
||
GPIOB->ODR^=0x2000; // indicate written two pages
|
||
}
|
||
// reading and writing rest bytes (less than two pages)
|
||
if(SizeApp != AppCount)
|
||
{
|
||
int NumOfLastBytes = SizeApp - AppCount;
|
||
|
||
*res_fresult = f_read(&MFile, Data2Write, NumOfLastBytes, &bytesRead);
|
||
|
||
if(*res_fresult != FR_OK) return;
|
||
|
||
AppCount += PAGE_SIZE*2;
|
||
|
||
*res_hal = FLASH_Write_Page(&app_current_add, Data2Write, NumOfLastBytes);
|
||
|
||
if(*res_hal != HAL_OK) return;
|
||
|
||
GPIOB->ODR^=0x2000;
|
||
}
|
||
|
||
*res_fresult = f_close(&MFile); // indicate written two pages
|
||
}
|
||
}
|
||
|
||
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) // writing first half of dma buffer (1 page)
|
||
{
|
||
if (huart->Instance == UART_BOOT)
|
||
{
|
||
if (FLAGS.InitOrWait)
|
||
{
|
||
HAL_StatusTypeDef res_hal;
|
||
|
||
if (FLAGS.InitBootPeriph) // if its first received page
|
||
{
|
||
//HAL_TIM_Base_Start_IT(&htim_boot); // start "wd" timer
|
||
FLAGS.InitBootPeriph = 0; // 5 sec silent on RX - mcu reset
|
||
}
|
||
|
||
res_hal = FLASH_Write_Page(&app_current_add, Data2Write, PAGE_SIZE);
|
||
if (res_hal != HAL_OK)
|
||
{
|
||
BOOTLOADER_ERRORS_COUNTERS.FLASH_WRITE++; // err when initialize uart
|
||
BOOTLOADER_ERRORS.FLASH_WRITE=1;
|
||
}
|
||
// HAL_UART_DMAStop(&huart_boot);
|
||
// HAL_UART_AbortReceive_IT(&huart_boot);
|
||
// HAL_UART_AbortReceive(&huart_boot);
|
||
|
||
FLAGS.HalfOfWrite = 1; // switch unwritten half of DMA buffer
|
||
|
||
cnt_tim_reset = 0; // upd WD Tim
|
||
GPIOB->ODR^=0x2000; // indicate written page
|
||
}
|
||
}
|
||
}
|
||
|
||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // writing second half of dma buffer (1 page)
|
||
{
|
||
if (huart->Instance == UART_BOOT)
|
||
{
|
||
if (FLAGS.InitOrWait == 0) // if its wait mode (not writting app)
|
||
{
|
||
// set Init mode, start WDTim after receiving first page
|
||
Check_CMD_USART(ReceiveDataUART); // check received uart data
|
||
FLAGS.InitOrWait = 1;
|
||
FLAGS.StartInit = 1;
|
||
FLAGS.InitBootPeriph = 1;
|
||
app_current_add = MAIN_APP_START_ADR; // set adress for app
|
||
}
|
||
else
|
||
{
|
||
HAL_StatusTypeDef res_hal;
|
||
res_hal = FLASH_Write_Page(&app_current_add, Data2Write+PAGE_SIZE, PAGE_SIZE);
|
||
if (res_hal != HAL_OK)
|
||
{
|
||
BOOTLOADER_ERRORS_COUNTERS.FLASH_WRITE++; // err when initialize uart
|
||
BOOTLOADER_ERRORS.FLASH_WRITE=1;
|
||
}
|
||
|
||
FLAGS.HalfOfWrite = 0; // switch unwritten half of DMA buffer
|
||
|
||
cnt_tim_reset = 0; // upd WD Tim
|
||
GPIOB->ODR^=0x2000; // indicate written page
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
uint32_t temp_app_cur_add;
|
||
int app_size;
|
||
/*void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||
{
|
||
|
||
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, CAN_Data) == HAL_OK)
|
||
{
|
||
#ifdef _CAN_PUSH_ID_TO_ADDR_
|
||
if(FLAGS.InitOrWait)
|
||
{ // if its 1 - Init: writting app.bin in flash
|
||
temp_app_cur_add = app_current_add+(RxHeader.ExtId&(0x0000FFFF));
|
||
|
||
FLASH_Write_Page(&temp_app_cur_add, CAN_Data, 8);
|
||
app_size-=8; // decrease app_size
|
||
if (app_size<=0) // when its gone - reset system and go to the app
|
||
{
|
||
__ASM("");
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
else
|
||
{ // if its 0 - Wait: parsing address to writting and size of app.bin
|
||
app_current_add = Data2Write[0]<<24 | Data2Write[1]<<16 | Data2Write[2]<<8 | Data2Write[3];
|
||
app_size = Data2Write[4]<<24 | Data2Write[5]<<16 | Data2Write[6]<<8 | Data2Write[7];
|
||
FLAGS.InitOrWait = 1; // switch to firmware (init)
|
||
}
|
||
#endif
|
||
if(FLAGS.InitOrWait)
|
||
{
|
||
if (FLAGS.InitBootPeriph) // if its first received page
|
||
{
|
||
HAL_TIM_Base_Start_IT(&htim_boot); // start "wd" timer
|
||
FLAGS.InitBootPeriph = 0; // 5 sec silent on RX - mcu reset
|
||
}
|
||
FLASH_Write_Page(&app_current_add, CAN_Data, 8);
|
||
cnt_tim_reset=0;
|
||
}
|
||
else
|
||
{
|
||
|
||
app_current_add = MAIN_APP_START_ADR; // set adress for app
|
||
Check_CMD_USART(CAN_Data);
|
||
FLAGS.InitBootPeriph=1;
|
||
FLAGS.InitOrWait = 1;
|
||
FLAGS.StartInit = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
*/
|
||
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
|
||
{
|
||
uint32_t er;
|
||
er = HAL_CAN_GetError(hcan);
|
||
__ASM("");
|
||
}
|
||
void Bootloader_TIM_Handler(void) // reset mcu after writing application is done
|
||
{ // add this to the TIM handler that is used (TIMx is seting up in project_setup.h)
|
||
HAL_StatusTypeDef res_fresult;
|
||
cnt_tim_reset++;
|
||
if (cnt_tim_reset > 5) // writing is done if there is silence on Rx for 5 second
|
||
{
|
||
if(FLAGS.BootloaderCMD==1)
|
||
{
|
||
FLAGS.InitMCUReady = 1;
|
||
ResetKey();
|
||
SetKey(); // write key for going to application
|
||
int NumOfLastBytes = (PAGE_SIZE - DMA1_Channel3->CNDTR%PAGE_SIZE); // read size of new data in dma buffer
|
||
if (NumOfLastBytes != 0)
|
||
{
|
||
res_fresult = FLASH_Write_Page(&app_current_add, Data2Write+PAGE_SIZE*FLAGS.HalfOfWrite, NumOfLastBytes); // writing last data
|
||
}
|
||
NVIC_SystemReset(); // reset mcu
|
||
}
|
||
else if(FLAGS.BootloaderCMD==2)
|
||
{
|
||
FLAGS.InitMCUReady = 1;
|
||
ResetKey();
|
||
SetKey();
|
||
NVIC_SystemReset();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void Check_CMD_USART(uint8_t *DataUART) // choose CMD (interface)
|
||
{ // 4 byte: 0xFF - erase app, else - just write app
|
||
//USART
|
||
if ((DataUART[0]|
|
||
DataUART[1]<<8|
|
||
DataUART[2]<<16) == 0xFFFFFF)
|
||
{
|
||
FLAGS.BootloaderCMD = 1;
|
||
}
|
||
//CAN
|
||
else if ((DataUART[0]|
|
||
DataUART[1]<<8|
|
||
DataUART[2]<<16) == 0xAAAFFF)
|
||
{
|
||
FLAGS.BootloaderCMD = 2;
|
||
}
|
||
//SDIO
|
||
else if ((DataUART[0]|
|
||
DataUART[1]<<8|
|
||
DataUART[2]<<16) == 0xAAFAFF)
|
||
{
|
||
FLAGS.BootloaderCMD = 3;
|
||
BSP_SD_DetectIT();
|
||
}
|
||
if (DataUART[3]== 0xFF)
|
||
{
|
||
FLAGS.reInitMCU = 1;
|
||
}
|
||
else
|
||
{
|
||
FLAGS.reInitMCU = 0;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
// reset/set key function
|
||
void SetKey(void)
|
||
{
|
||
HAL_FLASH_Unlock();
|
||
|
||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOOTLOADER_KEY_ADR, BL_KEY_APP_WRITTEN);
|
||
|
||
HAL_FLASH_Lock();
|
||
}
|
||
|
||
uint32_t ReadKey(void)
|
||
{
|
||
return (*(__IO uint32_t*)BOOTLOADER_KEY_ADR);
|
||
}
|
||
|
||
void ResetKey(void)
|
||
{
|
||
HAL_FLASH_Unlock();
|
||
uint32_t PageError = 0x00;
|
||
|
||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;// erase pages
|
||
EraseInitStruct.PageAddress = BOOTLOADER_KEY_ADR; //address
|
||
EraseInitStruct.NbPages = 0x01;// num of erased pages
|
||
|
||
HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
|
||
HAL_FLASH_Lock();
|
||
|
||
}
|
||
|
||
|
||
HAL_StatusTypeDef BSP_SD_ITConfig(void)
|
||
{
|
||
/* Code to be updated by the user or replaced by one from the FW pack (in a stmxxxx_sd.c file) */
|
||
GPIO_InitTypeDef gpio_init_structure;
|
||
|
||
/* Configure Interrupt mode for SD detection pin */
|
||
gpio_init_structure.Pin = SDIO_SDCard_In_PIN;
|
||
gpio_init_structure.Pull = GPIO_PULLUP;
|
||
gpio_init_structure.Speed = GPIO_SPEED_HIGH;
|
||
gpio_init_structure.Mode = GPIO_MODE_IT_RISING_FALLING;
|
||
HAL_GPIO_Init(SDIO_SDCard_In_PORT, &gpio_init_structure);
|
||
|
||
/* Enable and set SD detect EXTI Interrupt to the lowest priority */
|
||
HAL_NVIC_SetPriority((SDIO_SDCard_In_IRQn), 0x00, 0x00);
|
||
HAL_NVIC_EnableIRQ((SDIO_SDCard_In_IRQn));
|
||
|
||
return HAL_OK;
|
||
// return (uint8_t)0;
|
||
}
|
||
|
||
|
||
void BSP_SD_DetectIT(void)
|
||
{ // add this to the EXTI handler that is used (EXTIx (GPIO_PIN_x) is seting up in project_setup.h)
|
||
|
||
if(SDIO_SDCard_In_PORT->IDR&SDIO_SDCard_In_PIN)
|
||
FLAGS.SDCardIn = 0;
|
||
else
|
||
FLAGS.SDCardIn = 1;
|
||
}
|
||
|
||
|
||
void Boot_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_HSI;
|
||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
|
||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
|
||
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();
|
||
}
|
||
HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_1);
|
||
} |