|  | @@ -1,315 +1,522 @@
 | 
	
		
			
				|  |  | -#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 <math.h> 
 | 
	
		
			
				|  |  | -#include <string.h>
 | 
	
		
			
				|  |  | -#include <stdlib.h>
 | 
	
		
			
				|  |  | -#include <stdio.h>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -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);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +#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 "utility.h"
 | 
	
		
			
				|  |  | +#include <math.h> 
 | 
	
		
			
				|  |  | +#include <string.h>
 | 
	
		
			
				|  |  | +#include <stdlib.h>
 | 
	
		
			
				|  |  | +#include <stdio.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +SemaphoreHandle_t flash_mutex;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Флаг подтверждения новых сетевых параметров пользователем
 | 
	
		
			
				|  |  | +bool fConfirmWebParams = false;
 | 
	
		
			
				|  |  | +   
 | 
	
		
			
				|  |  | +// Системные настройки
 | 
	
		
			
				|  |  | +sys_settings_t sys_settings;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Общая структура настроек
 | 
	
		
			
				|  |  | +settings_t settings;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Настройки порта UART - RS485 (Modbus) в человеческом формате
 | 
	
		
			
				|  |  | +modbus_t mb_port_settings;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +void init_settings(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    flash_mutex = xSemaphoreCreateMutex();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Загрузка структуры настроек из flash
 | 
	
		
			
				|  |  | +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;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // Время ведения архива (сек.)
 | 
	
		
			
				|  |  | +    settings.period_archive = 3600;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +#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;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Установка параметров Modbus
 | 
	
		
			
				|  |  | +void settings_set_modbus_params(uint16_t mb_port)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	uint16_t param = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Количестро стоп бит (0-1 биты)
 | 
	
		
			
				|  |  | +	param = 0x0003 & mb_port; 
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (param == 0x00)
 | 
	
		
			
				|  |  | +		mb_port_settings.stopbits = STOP_1;
 | 
	
		
			
				|  |  | +	else if (param == 0x02)
 | 
	
		
			
				|  |  | +		mb_port_settings.stopbits = STOP_2;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Длина слова (2ой бит)
 | 
	
		
			
				|  |  | +	param = (0x0004 & mb_port) >> 2;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	mb_port_settings.databits = DATABITS_8;
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  | +	// Контроль четности (3-4 биты)
 | 
	
		
			
				|  |  | +	param = (0x0018 & mb_port) >> 3; 
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (param == 0x00)
 | 
	
		
			
				|  |  | +		mb_port_settings.parity = NO_PAR;
 | 
	
		
			
				|  |  | +	else if (param == 0x02)
 | 
	
		
			
				|  |  | +		mb_port_settings.parity = EVEN_PAR;
 | 
	
		
			
				|  |  | +	else if (param == 0x03)
 | 
	
		
			
				|  |  | +		mb_port_settings.parity = ODD_PAR;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// Скорость (5 - 7 биты)
 | 
	
		
			
				|  |  | +	param = (0x00E0 & mb_port) >> 5; 
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch (param)
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		case 0x00 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_2400;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x01 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_4800;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x02 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_9600;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x03 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_19200;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x04 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_38400;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x05 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_57600;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		case 0x06 :
 | 
	
		
			
				|  |  | +			mb_port_settings.baud = BRD_115200;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		default : break;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +uint32_t settings_get_mb_baud(modbus_t *mb_settings)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    switch (mb_settings->baud)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        case BRD_1200 :
 | 
	
		
			
				|  |  | +          return 1200;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_2400 :
 | 
	
		
			
				|  |  | +          return 2400;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_4800 :
 | 
	
		
			
				|  |  | +            return 4800;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_9600 :
 | 
	
		
			
				|  |  | +            return 9600;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_19200 :
 | 
	
		
			
				|  |  | +            return 19200;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_38400 :
 | 
	
		
			
				|  |  | +            return 38400;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_57600 :
 | 
	
		
			
				|  |  | +            return 57600;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_115200 :
 | 
	
		
			
				|  |  | +            return 115200;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_230400 :
 | 
	
		
			
				|  |  | +            return 230400;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case BRD_460800 :
 | 
	
		
			
				|  |  | +            return 460800;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        default :
 | 
	
		
			
				|  |  | +            return 115200; 
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +eMBParity settings_get_mb_par(modbus_t *mb_settings)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    switch (mb_settings->parity)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        case NO_PAR :
 | 
	
		
			
				|  |  | +            return MB_PAR_NONE;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case ODD_PAR :
 | 
	
		
			
				|  |  | +            return MB_PAR_ODD;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        case EVEN_PAR :
 | 
	
		
			
				|  |  | +            return MB_PAR_EVEN;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        default :
 | 
	
		
			
				|  |  | +            return MB_PAR_NONE;
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +void settings_init_mb_port(uint8_t mb_addr)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    uint32_t baud = settings_get_mb_baud(&mb_port_settings);
 | 
	
		
			
				|  |  | +    eMBParity par = settings_get_mb_par(&mb_port_settings);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    eMBInit(MB_RTU, mb_addr, 4, baud, par, mb_port_settings.stopbits);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Установить параметры дискретных входов по умолчанию
 | 
	
		
			
				|  |  | +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);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// -------------------------------------------------------------------------- //
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void settings_print(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    uint16_t foo = settings.com_settings.mb_port;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    printf("\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n");
 | 
	
		
			
				|  |  | +    printf("   Общие настройки для bootloader и FW");
 | 
	
		
			
				|  |  | +    printf("\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    printf("Настройки порта (Modbus): 0x%X\r\n", settings.com_settings.mb_port);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // stop bits
 | 
	
		
			
				|  |  | +    foo = settings.com_settings.mb_port & MB_STOP_BIT_MASK;
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    if (foo == MB_STOP_BIT_1)
 | 
	
		
			
				|  |  | +        printf("\tStop bits: STOP_1\r\n");
 | 
	
		
			
				|  |  | +    else if (foo == MB_STOP_BIT_2)
 | 
	
		
			
				|  |  | +        printf("\tStop bits: STOP_2\r\n");
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // parity
 | 
	
		
			
				|  |  | +    foo = settings.com_settings.mb_port & MB_PARITY_MASK;
 | 
	
		
			
				|  |  | +    if (foo == MB_NO_PAR)
 | 
	
		
			
				|  |  | +        printf("\tParity: NO_PAR\r\n");
 | 
	
		
			
				|  |  | +    else if (foo == MB_EVEN_PAR)
 | 
	
		
			
				|  |  | +        printf("\tParity: EVEN_PAR\r\n");
 | 
	
		
			
				|  |  | +    else if (foo == MB_ODD_PAR)
 | 
	
		
			
				|  |  | +        printf("\tParity: ODD_PAR\r\n");
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // baudrate
 | 
	
		
			
				|  |  | +    foo = settings.com_settings.mb_port & MB_BRD_MASK;
 | 
	
		
			
				|  |  | +    switch (foo) {
 | 
	
		
			
				|  |  | +        case MB_BRD_2400 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 2400\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_4800 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 4800\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_9600 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 9600\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_19200 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 19200\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_38400 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 38400\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_57600 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 57600\r\n"); break;
 | 
	
		
			
				|  |  | +        case MB_BRD_115200 :
 | 
	
		
			
				|  |  | +            printf("\tBaudrate: 115200\r\n"); break;
 | 
	
		
			
				|  |  | +        default : break;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    printf("Модель: %s\r\n", settings.com_settings.model);
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  | +}
 |