#include "settings.h" #include "cmsis_os.h" #include "config.h" #include CRC_HandleTypeDef hcrc; settings_t settings; static FLASH_EraseInitTypeDef EraseInitStruct; // void settings_crc_init(void) { hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; HAL_CRC_Init(&hcrc); } // void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc) { if(hcrc->Instance==CRC) { __HAL_RCC_CRC_CLK_ENABLE(); } } // void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc) { if(hcrc->Instance==CRC) { __HAL_RCC_CRC_CLK_DISABLE(); } } // void settings_load(void) { uint32_t load_crc; // CRC из flash uint32_t new_crc; // CRC загруженной структуры настроек settings_read_from_flash((uint8_t*)&settings, sizeof(settings)); // Считываем CRC из флеш памяти load_crc = (*(uint32_t*)GET_SETTINGS_CRC_ADDR(SETTINGS_PAGE)); // Рассчитываем CRC для структуры настроек new_crc = settings_get_crc(); // Если CRC не совпадают нужно прошивать дефолтные настройки if (load_crc != new_crc) { settings_set_def(); settings_save(); } } // bool settings_save(void) { uint32_t addr = GET_PAGE_ADDR(SETTINGS_PAGE); uint64_t *ptr = (uint64_t*)&settings; taskENTER_CRITICAL(); HAL_FLASH_Unlock(); settings_erase_page(SETTINGS_PAGE); save_settings_attributes(SETTINGS_PAGE); for (uint16_t i = 0; i < (sizeof(settings) / 8) + 1; i++) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, *ptr) != HAL_OK) { return false; } addr += 8; ptr++; } HAL_FLASH_Lock(); taskEXIT_CRITICAL(); return true; } // bool save_settings_attributes(uint16_t page) { uint32_t crc_addr = GET_SETTINGS_CRC_ADDR(page); uint32_t crc; crc = settings_get_crc(); if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, crc_addr, (uint64_t)crc) != HAL_OK) { return false; } return true; } // bool settings_erase_page(uint16_t page) { uint32_t bank_number = 0; uint32_t addr = 0; uint32_t PAGEError = 0; __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); addr = GET_PAGE_ADDR(page); bank_number = settings_get_bank(addr); EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.NbPages = 1; EraseInitStruct.Page = page; EraseInitStruct.Banks = bank_number; if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) return false; return true; } // uint32_t settings_get_bank(uint32_t addr) { return FLASH_BANK_1; } // void settings_set_def(void) { memset(settings.fw_version, 0, 20); strcpy(settings.fw_version, FW_VERSION); settings.motor_speed = 50; settings.support_speed = 60; settings.temperature_threshold = 70; } // uint32_t settings_get_crc(void) { __HAL_CRC_DR_RESET(&hcrc); return HAL_CRC_Calculate(&hcrc, (uint32_t*)&settings, sizeof(settings)); } // void settings_read_from_flash(uint8_t *data, uint32_t size) { uint32_t baseAddress = SETTINGS_ADDR; for (uint32_t i = 0; i < size; i++) *data++ = (*(uint32_t*)baseAddress++); } // void settings_test(void) { }