LCM — CH32V003 Light Control Module
Light Control Module, I2C slave
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1/********************************** (C) COPYRIGHT *******************************
2 * File Name : main.c
3 * Author : AAA
4 * Version : V1.0.0
5 * Date : 2026/06/26
6 * Description : Точка входа прошивки модуля освещения (LCM).
7 *
8 * Устройство: CH32V003F4P6 (WCH, RISC-V RV32EC).
9 * Роль на шине: I2C slave, адрес из NVM (заводской 0x7F).
10 * Исполнение: 8 реле (НО), 4 группы зон освещения.
11 *
12 * Разделение обязанностей:
13 * — main() + LCM_Module_Poll(): фон (NVM, reboot);
14 * — I2C1_EV/ER_IRQHandler в lcm_module.c: протокол RC↔LCM.
15 *
16 * Отладочный UART (115200) подключён через debug.c;
17 * в рабочем режиме управление — только по I2C.
18 *********************************************************************************/
19
20#include "debug.h"
21#include "user_data.h"
22#include "lcm_module.h"
23#include "event_log.h"
24
25/* IWDG timeout ~2 s при LSI ≈ 128 kHz: (999 + 1) * 256 / 128000 = 2.0 s */
26#define LCM_IWDG_PRESCALER IWDG_Prescaler_256
27#define LCM_IWDG_RELOAD 999U
28
29/*********************************************************************
30 * @fn LCM_IwdgInit
31 *
32 * @brief Инициализация Independent Watchdog (IWDG).
33 *
34 * @details IWDG тактируется от LSI (~128 kHz), который не запускается
35 * автоматически — без явного RCC_LSICmd(ENABLE) и ожидания
36 * RCC_FLAG_LSIRDY биты PVU/RVU в IWDG_STATR никогда не
37 * сбрасываются, а IWDG_Enable() ждёт LSIRDY (RSTSCKR бит 1)
38 * и виснет здесь навсегда — main() не доходит до while(1),
39 * из-за чего EventLog_Process()/LCM_Led_Poll() не выполняются
40 * (хотя I2C-команды всё равно исполняются — их обработка идёт
41 * в ISR независимо от основного цикла).
42 *
43 * Конфигурирует прескалер и reload, затем включает watchdog.
44 * После включения IWDG работает всегда до аппаратного reset.
45 */
46static void LCM_IwdgInit(void)
47{
48 RCC_LSICmd(ENABLE);
49 while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {
50 }
51
52 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
53 IWDG_SetPrescaler(LCM_IWDG_PRESCALER);
54 IWDG_SetReload(LCM_IWDG_RELOAD);
55
56 while (IWDG_GetFlagStatus(IWDG_FLAG_PVU) != RESET) {
57 }
58 while (IWDG_GetFlagStatus(IWDG_FLAG_RVU) != RESET) {
59 }
60
61 IWDG_ReloadCounter();
62 IWDG_Enable();
63}
64
65/*********************************************************************
66 * @fn main
67 *
68 * @brief Главная функция программы.
69 *
70 * @details Последовательность запуска:
71 *
72 * 1) NVIC_PriorityGroupConfig — 1 бит preemption, 3 бита subpriority
73 * (должно быть до NVIC_Init в модуле I2C).
74 * 2) SystemCoreClockUpdate — пересчёт частоты после reset (Delay, UART).
75 * 3) EventLog_Init — USART1 PD6, 115200 8N1, журнал событий.
76 * 4) Delay_Init — SysTick для Delay_Us / Delay_Ms.
77 * 5) UserData_Init — загрузка 26 байт пользовательской NVM в RAM-кэш;
78 * при ошибке — LCM_Module_ReportUserDataStatus() после Init.
79 * 6) LCM_Module_Init — GPIO реле, конфигурация из NVM, I2C slave.
80 * 7) LCM_IwdgInit — запуск IWDG для защиты от зависания.
81 *
82 * Основной цикл пустой с точки зрения прикладной логики реле:
83 * LCM_Module_Poll() обслуживает отложенную запись flash и перезагрузку;
84 * EventLog_Process() выводит буфер событий на UART;
85 * IWDG_ReloadCounter() подтверждает, что main-цикл жив.
86 * Все команды RC обрабатываются асинхронно в прерываниях I2C.
87 *
88 * @return none (функция не возвращает управление)
89 */
90int main(void)
91{
92 UserData_Status ud_st;
93
94 /* Группа приоритетов прерываний для I2C1_EV / I2C1_ER */
95 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
96
97 /* Актуальная частота ядра (HSI/PLL) для таймеров и UART */
99
102
103 Delay_Init();
104
105 ud_st = UserData_Init();
107
113
114 LCM_IwdgInit();
117
118 while (1) {
121 IWDG_ReloadCounter();
122 }
123}
void EventLog_Process(void)
Definition event_log.c:356
void EventLog_PushSystem(uint8_t tag)
Definition event_log.c:445
void EventLog_UserDataInit(UserData_Status st)
Definition event_log.c:404
void EventLog_BootBanner(void)
Definition event_log.c:396
void EventLog_LcmConfig(uint8_t i2c_addr, const uint8_t group_mask[4], uint8_t relay_state)
Definition event_log.c:414
void EventLog_Init(void)
Definition event_log.c:335
void LCM_Module_Poll(void)
Definition lcm_module.c:521
void LCM_Module_ReportUserDataStatus(UserData_Status st)
Definition lcm_module.c:452
uint8_t LCM_Module_GetI2cAddr(void)
Definition lcm_module.c:459
uint8_t LCM_Module_GetRelayState(void)
Definition lcm_module.c:464
const uint8_t * LCM_Module_GetGroupMasks(void)
Definition lcm_module.c:469
void LCM_Module_Init(void)
Definition lcm_module.c:483
#define LCM_IWDG_RELOAD
Definition main.c:27
#define LCM_IWDG_PRESCALER
Definition main.c:26
static void LCM_IwdgInit(void)
Definition main.c:46
int main(void)
Definition main.c:90
void SystemCoreClockUpdate(void)
UserData_Status UserData_Init(void)
Definition user_data.c:437
UserData_Status
Definition user_data.h:44