settings_api.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. #include "at32f403a_407.h"
  2. #include "settings_api.h"
  3. #include "sys_api.h"
  4. #include "FreeRTOS.h"
  5. #include "task.h"
  6. #include "queue.h"
  7. #include "semphr.h"
  8. #include "common_config.h"
  9. #include "common.h"
  10. #include "at32_uid.h"
  11. #include "hash.h"
  12. #include "utility.h"
  13. #include "log_api.h"
  14. #include <math.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. SemaphoreHandle_t flash_mutex;
  19. // Флаг подтверждения новых сетевых параметров пользователем
  20. bool fConfirmWebParams = false;
  21. // Системные настройки
  22. sys_settings_t sys_settings;
  23. // Копия системных настроек
  24. sys_settings_t temp_sys_settings;
  25. // Общая структура настроек
  26. settings_t settings;
  27. // Настройки порта UART - RS485 (Modbus) в человеческом формате
  28. modbus_t mb_port_settings;
  29. //
  30. void init_settings(void)
  31. {
  32. flash_mutex = xSemaphoreCreateMutex();
  33. }
  34. // Загрузка структуры настроек из flash
  35. void settings_load(settings_t *settings)
  36. {
  37. uint32_t loadCRC; // CRC из flash
  38. uint32_t newCRC; // CRC загруженной структуры настроек
  39. bool need_default = false;
  40. settings_read_from_flash((uint8_t*)settings, sizeof(settings_t));
  41. // Считываем CRC из флеш памяти
  42. loadCRC = (*(uint32_t*)CRC_ADDRESS);
  43. // Рассчитываем CRC для структуры настроек
  44. newCRC = settings_get_crc(settings);
  45. // Если CRC не совпадают нужно прошивать дефолтные настройки
  46. if (loadCRC != newCRC) {
  47. need_default = true;
  48. }
  49. // CRC совпала, проверяем контрольное слово если слово не совпадает
  50. // то это значит, что поплыла структура нстроек, прошиваем дефолт
  51. else if (settings->control_word != SETTINGS_CONTROL_WORD)
  52. {
  53. need_default = true;
  54. }
  55. // CRC и контрольное слово совпали, проверяем номер версии настроек.
  56. // Если версия в настройках и прошивке не совпадают
  57. // (при обновлении изменили структуру настроек), прошиваем дефолт
  58. else if (settings->settings_version != SETTINGS_VERSION)
  59. {
  60. need_default = true;
  61. }
  62. // Прошиваем дефолтные настройки если нужно
  63. if (need_default)
  64. {
  65. settings_set_all_default();
  66. settings_save(settings);
  67. }
  68. #if 1
  69. //SETTINGS_Print();
  70. #endif
  71. }
  72. //
  73. void settings_read_from_flash(uint8_t *data, uint32_t size)
  74. {
  75. uint32_t baseAddress = SETTINGS_SECTOR;
  76. for (uint32_t i = 0; i < size; i++)
  77. *data++ = (*(uint32_t*)baseAddress++);;
  78. }
  79. //
  80. uint32_t settings_get_crc(settings_t *settings)
  81. {
  82. crc_data_reset();
  83. return crc_block_calculate((uint32_t*)settings, sizeof(settings_t)/4 - 1);
  84. }
  85. //
  86. uint32_t settings_get_crit_sec_crc(settings_t *settings)
  87. {
  88. crc_data_reset();
  89. uint32_t critsec_len = (uint32_t)((uint8_t *)(&settings->critical_section_crc) - (uint8_t *)settings) / 4;
  90. return crc_block_calculate((uint32_t *)settings, critsec_len);
  91. }
  92. // Сброс всех настроек в значения по умолчанию
  93. void settings_set_all_default(void)
  94. {
  95. settings_set_modbus_def(&settings.com_settings.mb_port);
  96. //memset(settings.com_settings.model, 0, MODEL_LEN);
  97. //memcpy(settings.com_settings.model, MODEL_STR, strlen(MODEL_STR));
  98. settings.settings_version = SETTINGS_VERSION;
  99. settings.critical_section_crc = settings_get_crit_sec_crc(&settings);
  100. settings.control_word = SETTINGS_CONTROL_WORD;
  101. // Дискретные/счетные входы
  102. settings_din_def(&settings);
  103. // Выходы
  104. settings_do_def(&settings);
  105. // Безопасный режим
  106. settings.save_mode = 1;
  107. // Время ожидания опроса (сек.)
  108. settings.save_delay = 60;
  109. // Время ведения архива по каждому каналу (сек.)
  110. for (uint8_t i = 0; i < ARCH_CH_NUMBER; i++) {
  111. settings.period_archive[i] = 3600;
  112. }
  113. #if 0
  114. SETTINGS_SetWebParamsDef();
  115. SETTINGS_SetTempWebParamsDef();
  116. SETTINGS_SetInfoDef();
  117. SETTINGS_SetGSMDef();
  118. SETTINGS_SetFlagsDef();
  119. SETTINGS_SetEthternetSwitchDef();
  120. SETTINGS_SetSntpDef();
  121. SETTINGS_SetServerParamsDef();
  122. SETTINGS_SetProxyParamsDef();
  123. SETTINGS_SetPortGwDef();
  124. SETTINGS_SetPSDDef();
  125. SETTINGS_SetServiceDef();
  126. sSettings.settVer = SETTINGS_VERSION;
  127. sSettings.CritSecCRC = settings_get_crit_sec_crc();
  128. sSettings.controlWorld = SETTINGS_CONTROL_WORD;
  129. #endif
  130. }
  131. // -------------------------------------------------------------------------- //
  132. // Настройки по умолчанию
  133. //
  134. void settings_set_modbus_def(uint16_t *mb_port)
  135. {
  136. modbus_t mb_settings;
  137. mb_settings.baud = BRD_115200;
  138. mb_settings.parity = NO_PAR;
  139. mb_settings.databits = DATABITS_8;
  140. mb_settings.stopbits = STOP_1;
  141. settings_conv_modbus_def(&mb_settings, mb_port);
  142. }
  143. //
  144. void settings_conv_modbus_def(modbus_t *mb_settings, uint16_t *mb_port)
  145. {
  146. uint16_t param = 0;
  147. // Количестро стоп бит (0-1 биты)
  148. if (mb_settings->stopbits == STOP_1)
  149. param = 0x00;
  150. else if (mb_settings->stopbits == STOP_2)
  151. param = 0x02;
  152. // Длина слова (2ой бит)
  153. param |= 0x00 << 2;
  154. // Контроль четности (3-4 биты)
  155. if (mb_settings->parity == NO_PAR)
  156. param |= 0x00 << 3;
  157. else if (mb_settings->parity == EVEN_PAR)
  158. param |= 0x02 << 3;
  159. else if (mb_settings->parity == ODD_PAR)
  160. param |= 0x03 << 3;
  161. // Скорость (5 - 7 биты)
  162. switch (mb_settings->baud)
  163. {
  164. case BRD_2400 :
  165. param |= 0x00 << 5;
  166. break;
  167. case BRD_4800 :
  168. param |= 0x01 << 5;
  169. break;
  170. case BRD_9600 :
  171. param |= 0x02 << 5;
  172. break;
  173. case BRD_19200 :
  174. param |= 0x03 << 5;
  175. break;
  176. case BRD_38400 :
  177. param |= 0x04 << 5;
  178. break;
  179. case BRD_57600 :
  180. param |= 0x05 << 5;
  181. break;
  182. case BRD_115200 :
  183. param |= 0x06 << 5;
  184. break;
  185. default : break;
  186. }
  187. *mb_port = param;
  188. }
  189. // Установка параметров Modbus
  190. void settings_set_modbus_params(uint16_t mb_port)
  191. {
  192. uint16_t param = 0;
  193. // Количестро стоп бит (0-1 биты)
  194. param = 0x0003 & mb_port;
  195. if (param == 0x00)
  196. mb_port_settings.stopbits = STOP_1;
  197. else if (param == 0x02)
  198. mb_port_settings.stopbits = STOP_2;
  199. // Длина слова (2ой бит)
  200. param = (0x0004 & mb_port) >> 2;
  201. mb_port_settings.databits = DATABITS_8;
  202. // Контроль четности (3-4 биты)
  203. param = (0x0018 & mb_port) >> 3;
  204. if (param == 0x00)
  205. mb_port_settings.parity = NO_PAR;
  206. else if (param == 0x02)
  207. mb_port_settings.parity = EVEN_PAR;
  208. else if (param == 0x03)
  209. mb_port_settings.parity = ODD_PAR;
  210. // Скорость (5 - 7 биты)
  211. param = (0x00E0 & mb_port) >> 5;
  212. switch (param)
  213. {
  214. case 0x00 :
  215. mb_port_settings.baud = BRD_2400;
  216. break;
  217. case 0x01 :
  218. mb_port_settings.baud = BRD_4800;
  219. break;
  220. case 0x02 :
  221. mb_port_settings.baud = BRD_9600;
  222. break;
  223. case 0x03 :
  224. mb_port_settings.baud = BRD_19200;
  225. break;
  226. case 0x04 :
  227. mb_port_settings.baud = BRD_38400;
  228. break;
  229. case 0x05 :
  230. mb_port_settings.baud = BRD_57600;
  231. break;
  232. case 0x06 :
  233. mb_port_settings.baud = BRD_115200;
  234. break;
  235. default : break;
  236. }
  237. }
  238. //
  239. uint32_t settings_get_mb_baud(modbus_t *mb_settings)
  240. {
  241. switch (mb_settings->baud)
  242. {
  243. case BRD_1200 :
  244. return 1200;
  245. break;
  246. case BRD_2400 :
  247. return 2400;
  248. break;
  249. case BRD_4800 :
  250. return 4800;
  251. break;
  252. case BRD_9600 :
  253. return 9600;
  254. break;
  255. case BRD_19200 :
  256. return 19200;
  257. break;
  258. case BRD_38400 :
  259. return 38400;
  260. break;
  261. case BRD_57600 :
  262. return 57600;
  263. break;
  264. case BRD_115200 :
  265. return 115200;
  266. break;
  267. case BRD_230400 :
  268. return 230400;
  269. break;
  270. case BRD_460800 :
  271. return 460800;
  272. break;
  273. default :
  274. return 115200;
  275. break;
  276. }
  277. }
  278. //
  279. eMBParity settings_get_mb_par(modbus_t *mb_settings)
  280. {
  281. switch (mb_settings->parity)
  282. {
  283. case NO_PAR :
  284. return MB_PAR_NONE;
  285. break;
  286. case ODD_PAR :
  287. return MB_PAR_ODD;
  288. break;
  289. case EVEN_PAR :
  290. return MB_PAR_EVEN;
  291. break;
  292. default :
  293. return MB_PAR_NONE;
  294. break;
  295. }
  296. }
  297. //
  298. void settings_init_mb_port(uint8_t mb_addr)
  299. {
  300. uint32_t baud = settings_get_mb_baud(&mb_port_settings);
  301. eMBParity par = settings_get_mb_par(&mb_port_settings);
  302. eMBInit(MB_RTU, mb_addr, 4, baud, par, mb_port_settings.stopbits);
  303. }
  304. // Установить параметры дискретных входов по умолчанию
  305. void settings_din_def(settings_t *settings)
  306. {
  307. settings->di_mode_bits = 0;
  308. settings->di_norm_state_bits = 0;
  309. for (int i = 0; i < DI_NUMBER; i++) {
  310. settings->di_debounce[i] = 50;
  311. }
  312. }
  313. // Выходы
  314. void settings_do_def(settings_t *settings)
  315. {
  316. settings->do_mode_bits = 0; // режим работы выхода (обычный выход)
  317. settings->do_bits = 0; // последнее сохраненное значение
  318. settings->do_save_bits = 0;
  319. for (uint8_t i = 0; i < DO_NUMBER; i++)
  320. {
  321. settings->do_pwm[i] = 30;
  322. settings->do_pwm_save[i] = 30; // значение на выходах в бесопасном режиме работы
  323. settings->do_pwm_period[i] = 50;
  324. settings->do_pwm_period_save[i] = 50;
  325. }
  326. }
  327. // -------------------------------------------------------------------------- //
  328. // Запись структуры настроек во flash
  329. bool settings_save(settings_t *settings)
  330. {
  331. bool ret = false;
  332. xSemaphoreTake(flash_mutex, portMAX_DELAY);
  333. settings->critical_section_crc = settings_get_crit_sec_crc(settings);
  334. ret = settings_write_to_flash((uint8_t*)settings, sizeof(settings_t));
  335. xSemaphoreGive(flash_mutex);
  336. return ret;
  337. }
  338. //
  339. bool settings_save_with_log(void)
  340. {
  341. bool ret;
  342. // Изменились ли настройки
  343. bool change = settings_is_changed(&settings);
  344. // Сохранение настроек
  345. ret = settings_save(&settings);
  346. if (change) {
  347. log_add_entry(LOG_CHANGE_CONFIG, (log_event_state_t)ret, 0, 0);
  348. }
  349. return ret;
  350. }
  351. //
  352. bool settings_write_to_flash(uint8_t *data, uint32_t size)
  353. {
  354. uint32_t baseAddress = SETTINGS_SECTOR;
  355. uint32_t checkCrc = 0;
  356. uint32_t crc = settings_get_crc((settings_t*)data);
  357. flash_status_type status;
  358. uint8_t *ptr = data;
  359. flash_unlock();
  360. settings_erase_flash_sector();
  361. for (uint32_t i = 0; i < size; i++)
  362. if ((status = flash_byte_program(baseAddress++, *data++)) != FLASH_OPERATE_DONE) {
  363. DBG printf("FLASH_ProgramByte error: status = %d\r\n", status);
  364. return false;
  365. }
  366. if ((status = flash_word_program((uint32_t)CRC_ADDRESS, crc)) != FLASH_OPERATE_DONE) {
  367. DBG printf("FLASH_ProgramWord error: status = %d\r\n", status);
  368. }
  369. flash_lock();
  370. /* Считываем что записали */
  371. settings_read_from_flash(ptr, sizeof(settings_t));
  372. checkCrc = settings_get_crc((settings_t*)ptr);
  373. /* Проверяем CRC того что было записано */
  374. if ((checkCrc != crc) || (status != FLASH_OPERATE_DONE)) {
  375. return false;
  376. }
  377. return true;
  378. }
  379. // Очистка сектора настроек
  380. void settings_erase_flash_sector(void)
  381. {
  382. flash_status_type status;
  383. if ((status = flash_sector_erase(SETTINGS_SECTOR)) != FLASH_OPERATE_DONE) {
  384. DBG printf("SETTINGS_EraseFlashSector error: status = %d/r/n", status);
  385. }
  386. }
  387. //
  388. bool settings_is_changed(settings_t *new_settings)
  389. {
  390. uint32_t baseAddress = SETTINGS_SECTOR;
  391. uint32_t settings_size = sizeof(settings_t);
  392. uint8_t old_data;
  393. uint8_t new_data;
  394. uint8_t *ptr = (uint8_t*)new_settings;
  395. for (uint32_t i = 0; i < settings_size; i++)
  396. {
  397. old_data = (*(uint32_t*)baseAddress++);
  398. new_data = *ptr++;
  399. if (old_data != new_data)
  400. return true;
  401. }
  402. return false;
  403. }
  404. // -------------------------------------------------------------------------- //
  405. void settings_print(void)
  406. {
  407. uint16_t foo = settings.com_settings.mb_port;
  408. printf("\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n");
  409. printf(" Общие настройки для bootloader и FW");
  410. printf("\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");
  411. printf("Настройки порта (Modbus): 0x%X\r\n", settings.com_settings.mb_port);
  412. // stop bits
  413. foo = settings.com_settings.mb_port & MB_STOP_BIT_MASK;
  414. if (foo == MB_STOP_BIT_1)
  415. printf("\tStop bits: STOP_1\r\n");
  416. else if (foo == MB_STOP_BIT_2)
  417. printf("\tStop bits: STOP_2\r\n");
  418. // parity
  419. foo = settings.com_settings.mb_port & MB_PARITY_MASK;
  420. if (foo == MB_NO_PAR)
  421. printf("\tParity: NO_PAR\r\n");
  422. else if (foo == MB_EVEN_PAR)
  423. printf("\tParity: EVEN_PAR\r\n");
  424. else if (foo == MB_ODD_PAR)
  425. printf("\tParity: ODD_PAR\r\n");
  426. // baudrate
  427. foo = settings.com_settings.mb_port & MB_BRD_MASK;
  428. switch (foo) {
  429. case MB_BRD_2400 :
  430. printf("\tBaudrate: 2400\r\n"); break;
  431. case MB_BRD_4800 :
  432. printf("\tBaudrate: 4800\r\n"); break;
  433. case MB_BRD_9600 :
  434. printf("\tBaudrate: 9600\r\n"); break;
  435. case MB_BRD_19200 :
  436. printf("\tBaudrate: 19200\r\n"); break;
  437. case MB_BRD_38400 :
  438. printf("\tBaudrate: 38400\r\n"); break;
  439. case MB_BRD_57600 :
  440. printf("\tBaudrate: 57600\r\n"); break;
  441. case MB_BRD_115200 :
  442. printf("\tBaudrate: 115200\r\n"); break;
  443. default : break;
  444. }
  445. //printf("Модель: %s\r\n", settings.com_settings.model);
  446. }