#include "at32f403a_407.h" #include "settings_api.h" #include "sys_api.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "common_config.h" #include "common.h" #include "at32_uid.h" #include "hash.h" #include #include #include #include SemaphoreHandle_t flash_mutex; // Флаг подтверждения новых сетевых параметров пользователем bool fConfirmWebParams = false; // Системные настройки sys_settings_t sys_settings; // Общая структура настроек settings_t settings; // void init_settings(void) { flash_mutex = xSemaphoreCreateMutex(); } // Загрузка структуры настроек из flesh void settings_load(settings_t *settings) { uint32_t loadCRC; // CRC из flash uint32_t newCRC; // CRC загруженной структуры настроек bool need_default = false; settings_read_from_flash((uint8_t*)settings, sizeof(settings_t)); // Считываем CRC из флеш памяти loadCRC = (*(uint32_t*)CRC_ADDRESS); // Рассчитываем CRC для структуры настроек newCRC = settings_get_crc(settings); // Если CRC не совпадают нужно прошивать дефолтные настройки if (loadCRC != newCRC) { need_default = true; } // CRC совпала, проверяем контрольное слово если слово не совпадает // то это значит, что поплыла структура нстроек, прошиваем дефолт else if (settings->control_word != SETTINGS_CONTROL_WORD) { need_default = true; } // CRC и контрольное слово совпали, проверяем номер версии настроек. // Если версия в настройках и прошивке не совпадают // (при обновлении изменили структуру настроек), прошиваем дефолт else if (settings->settings_version != SETTINGS_VERSION) { need_default = true; } // Прошиваем дефолтные настройки если нужно if (need_default) { settings_set_all_default(); settings_save(settings); } #if 1 //SETTINGS_Print(); #endif } // void settings_read_from_flash(uint8_t *data, uint32_t size) { uint32_t baseAddress = SETTINGS_SECTOR; for (uint32_t i = 0; i < size; i++) *data++ = (*(uint32_t*)baseAddress++);; } // uint32_t settings_get_crc(settings_t *settings) { crc_data_reset(); return crc_block_calculate((uint32_t*)settings, sizeof(settings_t)/4 - 1); } // uint32_t settings_get_crit_sec_crc(settings_t *settings) { crc_data_reset(); uint32_t critsec_len = (uint32_t)((uint8_t *)(&settings->critical_section_crc) - (uint8_t *)settings) / 4; return crc_block_calculate((uint32_t *)settings, critsec_len); } // Сброс всех настроек в значения по умолчанию void settings_set_all_default(void) { settings_set_modbus_def(&settings.com_settings.mb_port); memset(settings.com_settings.model, 0, MODEL_LEN); memcpy(settings.com_settings.model, MODEL_STR, strlen(MODEL_STR)); settings.settings_version = SETTINGS_VERSION; settings.critical_section_crc = settings_get_crit_sec_crc(&settings); settings.control_word = SETTINGS_CONTROL_WORD; // Дискретные/счетные входы settings_din_def(&settings); // Выходы settings_do_def(&settings); // Безопасный режим settings.save_mode = 1; // Время ожидания опроса (сек.) settings.save_delay = 60; #if 0 SETTINGS_SetWebParamsDef(); SETTINGS_SetTempWebParamsDef(); SETTINGS_SetInfoDef(); SETTINGS_SetGSMDef(); SETTINGS_SetFlagsDef(); SETTINGS_SetEthternetSwitchDef(); SETTINGS_SetSntpDef(); SETTINGS_SetServerParamsDef(); SETTINGS_SetProxyParamsDef(); SETTINGS_SetPortGwDef(); SETTINGS_SetPSDDef(); SETTINGS_SetServiceDef(); sSettings.settVer = SETTINGS_VERSION; sSettings.CritSecCRC = settings_get_crit_sec_crc(); sSettings.controlWorld = SETTINGS_CONTROL_WORD; #endif } // -------------------------------------------------------------------------- // // Настройки по умолчанию // void settings_set_modbus_def(uint16_t *mb_port) { modbus_t mb_settings; mb_settings.baud = BRD_115200; mb_settings.parity = NO_PAR; mb_settings.databits = DATABITS_8; mb_settings.stopbits = STOP_1; settings_conv_modbus_def(&mb_settings, mb_port); } // void settings_conv_modbus_def(modbus_t *mb_settings, uint16_t *mb_port) { uint16_t param = 0; // Количестро стоп бит (0-1 биты) if (mb_settings->stopbits == STOP_1) param = 0x00; else if (mb_settings->stopbits == STOP_2) param = 0x02; // Длина слова (2ой бит) param |= 0x00 << 2; // Контроль четности (3-4 биты) if (mb_settings->parity == NO_PAR) param |= 0x00 << 3; else if (mb_settings->parity == EVEN_PAR) param |= 0x02 << 3; else if (mb_settings->parity == ODD_PAR) param |= 0x03 << 3; // Скорость (5 - 7 биты) switch (mb_settings->baud) { case BRD_2400 : param |= 0x00 << 5; break; case BRD_4800 : param |= 0x01 << 5; break; case BRD_9600 : param |= 0x02 << 5; break; case BRD_19200 : param |= 0x03 << 5; break; case BRD_38400 : param |= 0x04 << 5; break; case BRD_57600 : param |= 0x05 << 5; break; case BRD_115200 : param |= 0x06 << 5; break; default : break; } *mb_port = param; } // Установить параметры дискретных входов по умолчанию void settings_din_def(settings_t *settings) { settings->di_mode_bits = 0; settings->di_norm_state_bits = 0; for (int i = 0; i < DI_NUMBER; i++) { settings->di_debounce[i] = 50; } } // Выходы void settings_do_def(settings_t *settings) { settings->do_mode_bits = 0; // режим работы выхода (обычный выход) settings->do_bits = 0; // последнее сохраненное значение settings->do_save_bits = 0; for (uint8_t i = 0; i < DO_NUMBER; i++) { settings->do_pwm[i] = 30; settings->do_pwm_save[i] = 30; // значение на выходах в бесопасном режиме работы settings->do_pwm_period[i] = 50; settings->do_pwm_period_save[i] = 50; } } // -------------------------------------------------------------------------- // // Запись структуры настроек во flash void settings_save(settings_t *settings) { xSemaphoreTake(flash_mutex, portMAX_DELAY); settings->critical_section_crc = settings_get_crit_sec_crc(settings); settings_write_to_flash((uint8_t*)settings, sizeof(settings_t)); xSemaphoreGive(flash_mutex); } // void settings_write_to_flash(uint8_t *data, uint32_t size) { uint32_t baseAddress = SETTINGS_SECTOR; uint32_t checkCrc = 0; uint32_t crc = settings_get_crc((settings_t*)data); flash_status_type status; uint8_t *ptr = data; for (uint8_t i = 0; i < 3; i++) { flash_unlock(); settings_erase_flash_sector(); for (uint32_t i = 0; i < size; i++) if ((status = flash_byte_program(baseAddress++, *data++)) != FLASH_OPERATE_DONE) { DBG printf("FLASH_ProgramByte error: status = %d\r\n", status); break; } if ((status = flash_word_program((uint32_t)CRC_ADDRESS, crc)) != FLASH_OPERATE_DONE) { DBG printf("FLASH_ProgramWord error: status = %d\r\n", status); } flash_lock(); /* Считываем что записали */ settings_read_from_flash(ptr, sizeof(settings_t)); checkCrc = settings_get_crc((settings_t*)ptr); /* Проверяем CRC того что было записано */ if (checkCrc == crc) break; } } // Очистка сектора настроек void settings_erase_flash_sector(void) { flash_status_type status; if ((status = flash_sector_erase(SETTINGS_SECTOR)) != FLASH_OPERATE_DONE) { DBG printf("SETTINGS_EraseFlashSector error: status = %d/r/n", status); } }