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
*/
46
static
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
*/
90
int
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 */
98
SystemCoreClockUpdate
();
99
100
EventLog_Init
();
101
EventLog_BootBanner
();
102
103
Delay_Init();
104
105
ud_st =
UserData_Init
();
106
EventLog_UserDataInit
(ud_st);
107
108
LCM_Module_Init
();
109
LCM_Module_ReportUserDataStatus
(ud_st);
110
EventLog_LcmConfig
(
LCM_Module_GetI2cAddr
(),
111
LCM_Module_GetGroupMasks
(),
112
LCM_Module_GetRelayState
());
113
114
LCM_IwdgInit
();
115
EventLog_PushSystem
(2U);
116
EventLog_Process
();
117
118
while
(1) {
119
LCM_Module_Poll
();
120
EventLog_Process
();
121
IWDG_ReloadCounter();
122
}
123
}
EventLog_Process
void EventLog_Process(void)
Definition
event_log.c:356
EventLog_PushSystem
void EventLog_PushSystem(uint8_t tag)
Definition
event_log.c:445
EventLog_UserDataInit
void EventLog_UserDataInit(UserData_Status st)
Definition
event_log.c:404
EventLog_BootBanner
void EventLog_BootBanner(void)
Definition
event_log.c:396
EventLog_LcmConfig
void EventLog_LcmConfig(uint8_t i2c_addr, const uint8_t group_mask[4], uint8_t relay_state)
Definition
event_log.c:414
EventLog_Init
void EventLog_Init(void)
Definition
event_log.c:335
event_log.h
LCM_Module_Poll
void LCM_Module_Poll(void)
Definition
lcm_module.c:521
LCM_Module_ReportUserDataStatus
void LCM_Module_ReportUserDataStatus(UserData_Status st)
Definition
lcm_module.c:452
LCM_Module_GetI2cAddr
uint8_t LCM_Module_GetI2cAddr(void)
Definition
lcm_module.c:459
LCM_Module_GetRelayState
uint8_t LCM_Module_GetRelayState(void)
Definition
lcm_module.c:464
LCM_Module_GetGroupMasks
const uint8_t * LCM_Module_GetGroupMasks(void)
Definition
lcm_module.c:469
LCM_Module_Init
void LCM_Module_Init(void)
Definition
lcm_module.c:483
lcm_module.h
LCM_IWDG_RELOAD
#define LCM_IWDG_RELOAD
Definition
main.c:27
LCM_IWDG_PRESCALER
#define LCM_IWDG_PRESCALER
Definition
main.c:26
LCM_IwdgInit
static void LCM_IwdgInit(void)
Definition
main.c:46
main
int main(void)
Definition
main.c:90
SystemCoreClockUpdate
void SystemCoreClockUpdate(void)
Definition
system_ch32v00x.c:95
UserData_Init
UserData_Status UserData_Init(void)
Definition
user_data.c:437
user_data.h
UserData_Status
UserData_Status
Definition
user_data.h:44
User
main.c
Generated by
1.11.0