modbus_params.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. #include "at32f403a_407.h"
  2. #include "modbus_params.h"
  3. #include "io.h"
  4. #include "uptime.h"
  5. #include "rtc.h"
  6. #include "input.h"
  7. #include "output.h"
  8. #include "log.h"
  9. #include "settings_api.h"
  10. #include "common_config.h"
  11. #include "swap.h"
  12. #include <string.h>
  13. mb_param_t mb_param[MB_PARAM_MAX];
  14. uint32_t rtc_sinhro;
  15. // Пароль для установки системных настроек
  16. uint16_t psw;
  17. bool psw_ok = false;
  18. uint8_t fw_version[8];
  19. uint16_t save_sys_cmd = 0; // Команда сохранения системных настроек
  20. uint16_t system_cmd = 0; // Команда управления контроллером
  21. uint64_t value_64 = 0;
  22. uint8_t value_8 = 0;
  23. uint8_t arch_channel = 0;
  24. void get_time(uint8_t* buf, uint8_t size);
  25. void get_din_mode(uint8_t* buf, uint8_t size);
  26. void get_log_entries_number(uint8_t* buf, uint8_t size);
  27. void get_arch_ch_1(uint8_t* buf, uint8_t size);
  28. void get_arch_ch_2(uint8_t* buf, uint8_t size);
  29. void get_arch_ch_3(uint8_t* buf, uint8_t size);
  30. void get_arch_ch_4(uint8_t* buf, uint8_t size);
  31. void get_arch_ch_5(uint8_t* buf, uint8_t size);
  32. void get_arch_ch_6(uint8_t* buf, uint8_t size);
  33. void get_arch_ch_7(uint8_t* buf, uint8_t size);
  34. void get_arch_ch_8(uint8_t* buf, uint8_t size);
  35. void (*get_ch_entries_number[8])(uint8_t* buf, uint8_t size) = {
  36. get_arch_ch_1, get_arch_ch_2, get_arch_ch_3, get_arch_ch_4,
  37. get_arch_ch_5, get_arch_ch_6, get_arch_ch_7, get_arch_ch_8,
  38. };
  39. void get_rtc(uint8_t* buf, uint8_t size);
  40. //
  41. void mb_init_params(void)
  42. {
  43. uint16_t index = 0;
  44. uint16_t addr = 0;
  45. mb_param[index].reg = 0x0100;
  46. mb_param[index].size = 1;
  47. mb_param[index].param = (uint8_t*)&input_state_bit; // Текущее состояние входа
  48. mb_param[index].set = NULL;
  49. mb_param[index].get = NULL;
  50. mb_param[index].check_handler = mb_check_dummy;
  51. index++;
  52. // Счетчики импульсов. Регистры 0x0102 - 0x0111
  53. addr = 0x0102;
  54. for (int i = 0; i < DI_NUMBER; i++)
  55. {
  56. mb_param[index].reg = addr;
  57. mb_param[index].size = 2;
  58. mb_param[index].param = (uint8_t*)&input_cnt[i]; // Счетчик ипульсов
  59. mb_param[index].set = NULL;
  60. mb_param[index].get = NULL;
  61. mb_param[index].check_handler = mb_check_dummy;
  62. addr += 2;
  63. index++;
  64. }
  65. // Режим работы входов
  66. mb_param[index].reg = 0x0120;
  67. mb_param[index].size = 1;
  68. mb_param[index].param = (uint8_t*)&settings.di_mode_bits;
  69. mb_param[index].set = mb_set_din_mode;
  70. mb_param[index].get = NULL;
  71. mb_param[index].check_handler = mb_check_dummy;
  72. index++;
  73. // Нормальное состояние входов
  74. mb_param[index].reg = 0x0122;
  75. mb_param[index].size = 1;
  76. mb_param[index].param = (uint8_t*)&settings.di_norm_state_bits;
  77. mb_param[index].set = NULL;
  78. mb_param[index].get = NULL;
  79. mb_param[index].check_handler = mb_check_dummy;
  80. index++;
  81. // Счетчики импульсов. Регистры 0x0102 - 0x0111
  82. addr = 0x0124;
  83. for (int i = 0; i < DI_NUMBER; i++)
  84. {
  85. mb_param[index].reg = addr;
  86. mb_param[index].size = 1;
  87. mb_param[index].param = (uint8_t*)&settings.di_debounce[i]; // Счетчик ипульсов
  88. mb_param[index].set = NULL;
  89. mb_param[index].get = NULL;
  90. mb_param[index].check_handler = mb_check_dummy;
  91. addr++;
  92. index++;
  93. }
  94. // Текущее состояние выходов
  95. mb_param[index].reg = 0x0200;
  96. mb_param[index].size = 1;
  97. mb_param[index].param = (uint8_t*)&output_state_bit;
  98. mb_param[index].set = mb_set_do;
  99. mb_param[index].get = NULL;
  100. mb_param[index].check_handler = mb_check_dummy;
  101. index++;
  102. // Режим работы выходов
  103. mb_param[index].reg = 0x0202;
  104. mb_param[index].size = 1;
  105. mb_param[index].param = (uint8_t*)&output_mode_bit;
  106. mb_param[index].set = mb_set_do_mode;
  107. mb_param[index].get = NULL;
  108. mb_param[index].check_handler = mb_check_dummy;
  109. index++;
  110. // Состояние выходов в безопасном режиме
  111. mb_param[index].reg = 0x0203;
  112. mb_param[index].size = 1;
  113. mb_param[index].param = (uint8_t*)&settings.do_save_bits;
  114. mb_param[index].set = mb_set_do;
  115. mb_param[index].get = NULL;
  116. mb_param[index].check_handler = mb_check_dummy;
  117. index++;
  118. // Заполнение PWM. Регистры 0x0210 - 0x0217
  119. addr = 0x0210;
  120. for (int i = 0; i < DO_NUMBER; i++)
  121. {
  122. mb_param[index].reg = addr;
  123. mb_param[index].size = 1;
  124. mb_param[index].param = (uint8_t*)&output_pwm[i]; // Счетчик ипульсов
  125. mb_param[index].set = mb_set_do;
  126. mb_param[index].get = NULL;
  127. mb_param[index].check_handler = mb_check_dummy;
  128. addr++;
  129. index++;
  130. }
  131. // Заполнение PWM в безопасном режиме. Регистры 0x0220 - 0x0227
  132. addr = 0x0220;
  133. for (int i = 0; i < DO_NUMBER; i++)
  134. {
  135. mb_param[index].reg = addr;
  136. mb_param[index].size = 1;
  137. mb_param[index].param = (uint8_t*)&output_pwm_save[i]; // Счетчик ипульсов
  138. mb_param[index].set = mb_set_do;
  139. mb_param[index].get = NULL;
  140. mb_param[index].check_handler = mb_check_dummy;
  141. addr++;
  142. index++;
  143. }
  144. // Период PWM. Регистры 0x0220 - 0x0227
  145. addr = 0x0230;
  146. for (int i = 0; i < DO_NUMBER; i++)
  147. {
  148. mb_param[index].reg = addr;
  149. mb_param[index].size = 1;
  150. mb_param[index].param = (uint8_t*)&output_pwm_period[i]; // Счетчик ипульсов
  151. mb_param[index].set = mb_set_do;
  152. mb_param[index].get = NULL;
  153. mb_param[index].check_handler = mb_check_dummy;
  154. addr++;
  155. index++;
  156. }
  157. // Период PWM. Регистры 0x0220 - 0x0227
  158. addr = 0x0240;
  159. for (int i = 0; i < DO_NUMBER; i++)
  160. {
  161. mb_param[index].reg = addr;
  162. mb_param[index].size = 1;
  163. mb_param[index].param = (uint8_t*)&output_pwm_period_save[i]; // Счетчик ипульсов
  164. mb_param[index].set = mb_set_do;
  165. mb_param[index].get = NULL;
  166. mb_param[index].check_handler = mb_check_dummy;
  167. addr++;
  168. index++;
  169. }
  170. // ---------------------------------------------------------------------- //
  171. // Управление контроллером. Разные параметры.
  172. // ---------------------------------------------------------------------- //
  173. // Управление контроллером
  174. mb_param[index].reg = 0x0800;
  175. mb_param[index].size = 1;
  176. mb_param[index].param = (uint8_t*)&system_cmd; //
  177. mb_param[index].set = mb_control;
  178. mb_param[index].get = NULL;
  179. mb_param[index].check_handler = mb_check_dummy;
  180. index++;
  181. // uptime
  182. mb_param[index].reg = 0x0801;
  183. mb_param[index].size = 2;
  184. mb_param[index].param = (uint8_t*)&uptime; //
  185. mb_param[index].set = NULL;
  186. mb_param[index].get = NULL;
  187. mb_param[index].check_handler = mb_check_dummy;
  188. index++;
  189. // RTC
  190. mb_param[index].reg = 0x0803;
  191. mb_param[index].size = 4;
  192. mb_param[index].param = (uint8_t*)&value_64; //
  193. mb_param[index].set = mb_set_rtc;
  194. mb_param[index].get = get_rtc;
  195. mb_param[index].check_handler = mb_check_dummy;
  196. index++;
  197. // ---------------------------------------------------------------------- //
  198. // Журналы/рахивы
  199. // ---------------------------------------------------------------------- //
  200. // Емкость журнала (максимальная)
  201. mb_param[index].reg = 0x0900;
  202. mb_param[index].size = 1;
  203. mb_param[index].param = (uint8_t*)&log_entries_capacity; //
  204. mb_param[index].set = NULL;
  205. mb_param[index].get = NULL;
  206. mb_param[index].check_handler = mb_check_dummy;
  207. index++;
  208. // Текущее количество записей в журнале
  209. mb_param[index].reg = 0x0901;
  210. mb_param[index].size = 1;
  211. mb_param[index].param = NULL; //
  212. mb_param[index].set = NULL;
  213. mb_param[index].get = get_log_entries_number;
  214. mb_param[index].check_handler = mb_check_dummy;
  215. index++;
  216. // Емкость архива (максимальная)
  217. mb_param[index].reg = 0x0902;
  218. mb_param[index].size = 1;
  219. mb_param[index].param = (uint8_t*)&archive_entries_capacity; //
  220. mb_param[index].set = NULL;
  221. mb_param[index].get = NULL;
  222. mb_param[index].check_handler = mb_check_dummy;
  223. index++;
  224. // Текущее количество записей в архиве по каждому каналу
  225. addr = 0x0903;
  226. for (int i = 0; i < ARCH_CH_NUMBER; i++)
  227. {
  228. mb_param[index].reg = addr;
  229. mb_param[index].size = 1;
  230. mb_param[index].param = NULL;
  231. mb_param[index].set = NULL;
  232. mb_param[index].get = get_ch_entries_number[i];
  233. mb_param[index].check_handler = mb_check_dummy;
  234. addr++;
  235. index++;
  236. }
  237. // Период архива. Регистры 0x0904 - 0x090B
  238. addr = 0x090B;
  239. for (int i = 0; i < ARCH_CH_NUMBER; i++)
  240. {
  241. mb_param[index].reg = addr;
  242. mb_param[index].size = 1;
  243. mb_param[index].param = (uint8_t*)&settings.period_archive[i]; // Счетчик ипульсов
  244. mb_param[index].set = NULL;
  245. mb_param[index].get = NULL;
  246. mb_param[index].check_handler = mb_check_archiv_per;
  247. addr++;
  248. index++;
  249. }
  250. // ---------------------------------------------------------------------- //
  251. // Системные настройки
  252. // ---------------------------------------------------------------------- //
  253. // Код модели (только чтение). Определяется прошивкой.
  254. mb_param[index].reg = 0x0080;
  255. mb_param[index].size = 1;
  256. mb_param[index].param = (uint8_t*)&model_code; //
  257. mb_param[index].set = NULL;
  258. mb_param[index].get = NULL;
  259. mb_param[index].check_handler = mb_check_dummy;
  260. index++;
  261. // Дата производства Unix формат (чтение/запись по паролю)
  262. mb_param[index].reg = 0x0081;
  263. mb_param[index].size = 2;
  264. mb_param[index].param = (uint8_t*)&temp_sys_settings.prod_date; //
  265. mb_param[index].set = NULL;
  266. mb_param[index].get = NULL;
  267. mb_param[index].check_handler = mb_check_dummy;
  268. index++;
  269. // Серийный номер (чтение/запись по паролю).
  270. mb_param[index].reg = 0x0083;
  271. mb_param[index].size = 2;
  272. mb_param[index].param = (uint8_t*)&temp_sys_settings.sn; //
  273. mb_param[index].set = NULL;
  274. mb_param[index].get = NULL;
  275. mb_param[index].check_handler = mb_check_dummy;
  276. index++;
  277. // Версия ПО (только чтение).
  278. memcpy(&fw_version, FW_VERSION, 8);
  279. mb_param[index].reg = 0x0085;
  280. mb_param[index].size = 4;
  281. mb_param[index].param = (uint8_t*)&fw_version; //
  282. mb_param[index].set = NULL;
  283. mb_param[index].get = NULL;
  284. mb_param[index].check_handler = mb_check_dummy;
  285. index++;
  286. // Статус тестирования (чтение/запись по паролю).
  287. mb_param[index].reg = 0x0089;
  288. mb_param[index].size = 1;
  289. mb_param[index].param = (uint8_t*)&temp_sys_settings.test_state; //
  290. mb_param[index].set = NULL;
  291. mb_param[index].get = NULL;
  292. mb_param[index].check_handler = mb_check_dummy;
  293. index++;
  294. // Пароль
  295. mb_param[index].reg = 0x008A;
  296. mb_param[index].size = 1;
  297. mb_param[index].param = (uint8_t*)&psw; //
  298. mb_param[index].set = mb_password;
  299. mb_param[index].get = NULL;
  300. mb_param[index].check_handler = mb_check_dummy;
  301. index++;
  302. // Команда на сохранение системных настроек
  303. mb_param[index].reg = 0x008B;
  304. mb_param[index].size = 1;
  305. mb_param[index].param = (uint8_t*)&save_sys_cmd; //
  306. mb_param[index].set = mb_sys_settings_save;
  307. mb_param[index].get = NULL;
  308. mb_param[index].check_handler = mb_check_dummy;
  309. index++;
  310. }
  311. // Возвращает размер параметра в регистрах
  312. bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size)
  313. {
  314. for (uint16_t i = 0; i < MB_PARAM_MAX; i++)
  315. {
  316. if (mb_param[i].reg == reg)
  317. {
  318. *index = i;
  319. *size = mb_param[i].size;
  320. return true;
  321. }
  322. }
  323. return false;
  324. }
  325. //
  326. mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index)
  327. {
  328. uint8_t *ptr = mb_param[index].param;
  329. // Если параметр только для чтения
  330. if (mb_param[index].check_handler == NULL)
  331. return MB_NO_ACTION;
  332. for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
  333. {
  334. *ptr = buf[2*mb_param[index].size - 1 - i];
  335. ptr++;
  336. }
  337. /*
  338. if (mb_param[index].check_handler != NULL)
  339. mb_param[index].check_handler();
  340. */
  341. mb_param[index].check_handler();
  342. if (mb_param[index].set != NULL)
  343. return mb_param[index].set();
  344. else
  345. return MB_NO_ACTION;
  346. /*
  347. if (mb_param[index].f_activity)
  348. return mb_param[index].set_handler();
  349. else
  350. return MB_NO_ACTION;
  351. */
  352. }
  353. //
  354. void mb_get_param(uint8_t *buf, uint16_t index)
  355. {
  356. uint8_t *ptr;
  357. if (mb_param[index].get != NULL) {
  358. mb_param[index].get(buf, mb_param[index].size);
  359. return;
  360. }
  361. ptr = mb_param[index].param + 2*mb_param[index].size - 1;
  362. for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
  363. {
  364. *buf = *ptr;
  365. buf++;
  366. ptr--;
  367. }
  368. }
  369. // -------------------------------------------------------------------------- //
  370. // Чтение параметров
  371. // -------------------------------------------------------------------------- //
  372. #if 0
  373. void get_time(uint8_t* buf, uint8_t size)
  374. {
  375. uint32_t rtc_unix = RTC_GetUnixTime();
  376. uint8_t *ptr = (uint8_t*)&rtc_unix + 2*size - 1;
  377. for (uint16_t i = 0; i < 2*size; i++)
  378. {
  379. *buf = *ptr;
  380. buf++;
  381. ptr--;
  382. }
  383. }
  384. #endif
  385. //
  386. void get_din_mode(uint8_t* buf, uint8_t size)
  387. {
  388. }
  389. //
  390. void get_log_entries_number(uint8_t* buf, uint8_t size)
  391. {
  392. static uint16_t capacity;
  393. capacity = swap_uint16(log_capacity());
  394. memcpy(buf, &capacity, 2);
  395. //buf = (uint8_t*)&capacity;
  396. }
  397. //
  398. void get_arch_ch_1(uint8_t* buf, uint8_t size)
  399. {
  400. static uint16_t capacity;
  401. capacity = swap_uint16(log_arch_capacity(0));
  402. memcpy(buf, &capacity, 2);
  403. }
  404. //
  405. void get_arch_ch_2(uint8_t* buf, uint8_t size)
  406. {
  407. static uint16_t capacity;
  408. capacity = swap_uint16(log_arch_capacity(1));
  409. memcpy(buf, &capacity, 2);
  410. }
  411. //
  412. void get_arch_ch_3(uint8_t* buf, uint8_t size)
  413. {
  414. static uint16_t capacity;
  415. capacity = swap_uint16(log_arch_capacity(2));
  416. memcpy(buf, &capacity, 2);
  417. }
  418. //
  419. void get_arch_ch_4(uint8_t* buf, uint8_t size)
  420. {
  421. static uint16_t capacity;
  422. capacity = swap_uint16(log_arch_capacity(3));
  423. memcpy(buf, &capacity, 2);
  424. }
  425. //
  426. void get_arch_ch_5(uint8_t* buf, uint8_t size)
  427. {
  428. static uint16_t capacity;
  429. capacity = swap_uint16(log_arch_capacity(4));
  430. memcpy(buf, &capacity, 2);
  431. }
  432. //
  433. void get_arch_ch_6(uint8_t* buf, uint8_t size)
  434. {
  435. static uint16_t capacity;
  436. capacity = swap_uint16(log_arch_capacity(5));
  437. memcpy(buf, &capacity, 2);
  438. }
  439. //
  440. void get_arch_ch_7(uint8_t* buf, uint8_t size)
  441. {
  442. static uint16_t capacity;
  443. capacity = swap_uint16(log_arch_capacity(6));
  444. memcpy(buf, &capacity, 2);
  445. }
  446. //
  447. void get_arch_ch_8(uint8_t* buf, uint8_t size)
  448. {
  449. static uint16_t capacity;
  450. capacity = swap_uint16(log_arch_capacity(7));
  451. memcpy(buf, &capacity, 2);
  452. }
  453. //
  454. void get_rtc(uint8_t* buf, uint8_t size)
  455. {
  456. uint64_t rtc = swap_uint64(rtc_get_ms());
  457. memcpy(buf, &rtc, 8);
  458. }
  459. // -------------------------------------------------------------------------- //
  460. // Установка параметров
  461. // -------------------------------------------------------------------------- //
  462. //
  463. mb_delay_action_t mb_set_din_mode(void)
  464. {
  465. in_set();
  466. return MB_NO_ACTION;
  467. }
  468. //
  469. mb_delay_action_t mb_set_do(void)
  470. {
  471. //do_set();
  472. do_set_common();
  473. return MB_NO_ACTION;
  474. }
  475. //
  476. mb_delay_action_t mb_set_do_mode(void)
  477. {
  478. do_set_mode();
  479. return MB_NO_ACTION;
  480. }
  481. //
  482. mb_delay_action_t mb_set_time(void)
  483. {
  484. TM_RTC_SetDataTimeUnix(rtc_sinhro);
  485. return MB_NO_ACTION;
  486. }
  487. //
  488. mb_delay_action_t mb_password(void)
  489. {
  490. if (psw != MB_PASSWORD)
  491. return MB_PAS_ERR;
  492. else {
  493. if (psw_ok == false) {
  494. psw_ok = true;
  495. return MB_PAS_OK;
  496. }
  497. else
  498. return MB_NO_ACTION;
  499. }
  500. }
  501. //
  502. mb_delay_action_t mb_sys_settings_save(void)
  503. {
  504. if (save_sys_cmd == 1)
  505. return MB_SAVE_SYS_SETTINGS;
  506. else
  507. return MB_NO_ACTION;
  508. }
  509. //
  510. mb_delay_action_t mb_control(void)
  511. {
  512. if (system_cmd == MB_COM_SETTINGS_SAVE)
  513. return MB_SAVE_SETTINGS;
  514. else if (system_cmd == MB_COM_LOG_CLEAR)
  515. return MB_LOG_CLEAR;
  516. else if ((system_cmd >= (uint8_t)MB_COM_ARCH_CLEAR_1) && (system_cmd <= (uint8_t)MB_COM_ARCH_CLEAR_8)) {
  517. arch_channel = system_cmd;
  518. return MB_ARCHIVE_CLEAR;
  519. }
  520. return MB_NO_ACTION;
  521. #if 0
  522. if (system_cmd == 1)
  523. return MB_SAVE_SETTINGS;
  524. else if (system_cmd == 2)
  525. return MB_DEF_SETTINGS;
  526. else if (system_cmd == 3)
  527. return MB_RESET;
  528. else if (system_cmd == 4)
  529. return MB_PART_DEF_SETTINGS;
  530. return MB_NO_ACTION;
  531. #endif
  532. }
  533. //
  534. mb_delay_action_t mb_set_rtc(void)
  535. {
  536. float delta;
  537. uint64_t now = rtc_get_ms();
  538. if (now >= value_64)
  539. delta = (float)(now - value_64);
  540. else
  541. delta = (float)(value_64 - now);
  542. rtc_set_in_ms((uint32_t)(value_64/1000));
  543. // -------------------------------------------------------------------------- //
  544. // EVENT. Перевод времени.
  545. log_add_entry(LOG_CLOCK_CHANGE, LOG_EVENT_STATE_OK, 0, delta);
  546. return MB_NO_ACTION;
  547. }
  548. // -------------------------------------------------------------------------- //
  549. // Проверка параметров //
  550. // -------------------------------------------------------------------------- //
  551. //
  552. void mb_check_dummy(void)
  553. {
  554. }
  555. //
  556. void mb_check_archiv_per(void)
  557. {
  558. for (uint8_t i = 0; i < ARCH_CH_NUMBER; i++)
  559. {
  560. if (settings.period_archive[i] > (uint16_t)MAX_ARCHIVE_PERIOD)
  561. settings.period_archive[i] = (uint16_t)MAX_ARCHIVE_PERIOD;
  562. }
  563. }