style: big renaming

This commit is contained in:
aZholtikov committed 2026-10-31 07:37:20 +03:00
1 parent e334aec37f
commit 5a8094e9ff
2 files changed
+204 -204

No files matched your search

+57 -57
View File
@@ -25,7 +25,7 @@
Прошивка не использует динамическое выделение памяти. Все данные хранятся в статической области и регистрах микроконтроллера.
Пакет формируется в глобальной переменной `transmitted_data` типа `zh_nrf24_sensor_transmitted_data_t` из внешней библиотеки `zh_nrf24_config` и сериализуется функцией `zh_nrf24_sensor_build_payload()` перед передачей.
Пакет формируется в глобальной переменной `_transmitted_data` типа `zh_nrf24_sensor_transmitted_data_t` из внешней библиотеки `zh_nrf24_config` и сериализуется функцией `zh_nrf24_sensor_build_payload()` перед передачей.
| Поле | Тип | Описание |
| ------ | ----- | ---------- |
@@ -47,83 +47,83 @@
### Управление памятью
Прошивка не использует динамическую память. Глобальная переменная `transmitted_data` заполняется при старте (идентификатор и тип), в рабочем цикле обновляется только поле `battery`. Флаги `send_request`, `nrf_event` объявлены как `static volatile uint8_t` для корректного доступа из ISR и главного цикла.
Прошивка не использует динамическую память. Глобальная переменная `_transmitted_data` заполняется при старте (идентификатор и тип), в рабочем цикле обновляется только поле `battery`. Флаги `_send_request`, `_nrf_event` объявлены как `static volatile bool` для корректного доступа из ISR и главного цикла.
### Флаги синхронизации
| Флаг | Устанавливается | Используется |
| ------ | ----------------- | -------------- |
| `send_request` | ISR `INT1_vect` (касание) | Главный цикл — запуск передачи |
| `nrf_event` | ISR `INT0_vect` (IRQ nRF24) | Конечный автомат сопряжения |
| `_send_request` | ISR `INT1_vect` (касание) | Главный цикл — запуск передачи |
| `_nrf_event` | ISR `INT0_vect` (IRQ nRF24) | Конечный автомат сопряжения |
---
## API (интерфейс)
Все функции являются `static` и доступны только внутри модуля `main.c`.
Все функции являются `static` и доступны только внутри модуля `src/zh_avr_touch_pad.c`. Имена функций имеют префикс `_zh_`.
### Инициализация
| Функция | Описание |
| --------- | ---------- |
| `zh_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию |
| `zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) |
| `zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи |
| `zh_nrf24_interrupt_init()` | Настройка внешнего прерывания INT0 (PD2, falling edge) для сигнала IRQ nRF24 |
| `_zh_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию |
| `_zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) |
| `_zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи |
| `_zh_nrf24_interrupt_init()` | Настройка внешнего прерывания INT0 (PD2, falling edge) для сигнала IRQ nRF24 |
### Работа с EEPROM
| Функция | Описание |
|---------|----------|
| `zh_load_device_id()` | Чтение идентификатора устройства из EEPROM, возврат `DEVICE_ID_UNASSIGNED` если не сохранён |
| `zh_save_device_id()` | Сохранение идентификатора устройства в EEPROM |
| `_zh_load_device_id()` | Чтение идентификатора устройства из EEPROM, возврат `DEVICE_ID_UNASSIGNED` если не сохранён |
| `_zh_save_device_id()` | Сохранение идентификатора устройства в EEPROM |
### Измерение
| Функция | Описание |
|---------|----------|
| `zh_get_battery_voltage()` | Измерение напряжения батареи через внутренний АЦП с опорой 1,1 В, возврат значения в вольтах |
| `zh_get_random_token()` | Генерация 16-битного псевдослучайного токена из шума АЦП и MCUSR для запроса сопряжения |
| `_zh_get_battery_voltage()` | Измерение напряжения батареи через внутренний АЦП с опорой 1,1 В, возврат значения в вольтах |
| `_zh_get_random_token()` | Генерация 16-битного псевдослучайного токена из шума АЦП и MCUSR для запроса сопряжения |
### Передача данных
| Функция | Описание |
|---------|----------|
| `zh_nrf24_send()` | Блокирующая передача буфера через nRF24L01+ с ожиданием завершения по пину IRQ (таймаут 100 мс) |
| `zh_nrf24_send_no_wait()` | Неблокирующая передача — загружает буфер, импульс CE 15 мкс, завершение по прерыванию IRQ |
| `_zh_nrf24_send()` | Блокирующая передача буфера через nRF24L01+ с ожиданием завершения по пину IRQ (таймаут 100 мс) |
| `_zh_nrf24_send_no_wait()` | Неблокирующая передача — загружает буфер, импульс CE 15 мкс, завершение по прерыванию IRQ |
### Управление режимами nRF24L01+
| Функция | Описание |
|---------|----------|
| `zh_nrf24_enter_rx()` | Переключение nRF24L01+ в режим приёма на трубе 0 |
| `zh_nrf24_enter_power_down()` | Перевод nRF24L01+ в режим Power Down |
| `_zh_nrf24_enter_rx()` | Переключение nRF24L01+ в режим приёма на трубе 0 |
| `_zh_nrf24_enter_power_down()` | Перевод nRF24L01+ в режим Power Down |
### Низкоуровневые SPI-операции
| Функция | Описание |
| --------- | ---------- |
| `zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) |
| `zh_nrf24_send_command()` | Отправка однобайтовой команды и чтение регистра статуса |
| `zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ |
| `zh_nrf24_write_buff_register()` | Запись многобайтового буфера в регистр nRF24L01+ |
| `zh_nrf24_write_buffer()` | Запись буфера данных с указанной SPI-командой |
| `zh_nrf24_read_payload()` | Чтение принятого пакета из RX FIFO nRF24 в буфер |
| `zh_nrf24_read_payload_width()` | Чтение длины пакета в RX FIFO nRF24 |
| `_zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) |
| `_zh_nrf24_send_command()` | Отправка однобайтовой команды и чтение регистра статуса |
| `_zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ |
| `_zh_nrf24_write_buff_register()` | Запись многобайтового буфера в регистр nRF24L01+ |
| `_zh_nrf24_write_buffer()` | Запись буфера данных с указанной SPI-командой |
| `_zh_nrf24_read_payload()` | Чтение принятого пакета из RX FIFO nRF24 в буфер |
| `_zh_nrf24_read_payload_width()` | Чтение длины пакета в RX FIFO nRF24 |
### Watchdog-таймер
| Функция | Описание |
|---------|----------|
| `zh_wdt_start()` | Запуск watchdog-таймера в режиме прерывания с указанным таймаутом |
| `zh_wdt_stop()` | Остановка watchdog-таймера |
| `_zh_wdt_start()` | Запуск watchdog-таймера в режиме прерывания с указанным таймаутом |
| `_zh_wdt_stop()` | Остановка watchdog-таймера |
### Сон и сопряжение
| Функция | Описание |
|---------|----------|
| `zh_do_pairing()` | Запуск конечного автомата сопряжения со шлюзом для получения идентификатора |
| `zh_enter_final_sleep()` | Переход в окончательный Power-down сон до сброса: отключение всех прерываний, watchdog, радиомодуля, АЦП, SPI и неиспользуемых периферийных блоков |
| `_zh_do_pairing()` | Запуск конечного автомата сопряжения со шлюзом для получения идентификатора |
| `_zh_enter_final_sleep()` | Переход в окончательный Power-down сон до сброса: отключение всех прерываний, watchdog, радиомодуля, АЦП, SPI и неиспользуемых периферийных блоков |
---
@@ -131,9 +131,9 @@
Прошивка работает на bare-metal AVR без RTOS. Синхронизация между прерываниями и главным циклом реализуется следующим образом:
1. **Флаги `volatile`** — переменные `send_request`, `nrf_event` объявлены как `static volatile uint8_t`, что гарантирует чтение актуального значения из памяти при каждой проверке в главном цикле.
1. **Флаги `volatile`** — переменные `_send_request`, `_nrf_event` объявлены как `static volatile bool`, что гарантирует чтение актуального значения из памяти при каждой проверке в главном цикле.
2. **Атомарная запись из ISR** — обработка прерывания устанавливает флаг в `true`. Запись одного байта на AVR является атомарной операцией.
3. **Отключение прерываний при проверке и сбросе флага** — `cli()` перед проверкой и сбросом `send_request` в главном цикле исключает гонку между ISR и главным циклом.
3. **Отключение прерываний при проверке и сбросе флага** — `cli()` перед проверкой и сбросом `_send_request` в главном цикле исключает гонку между ISR и главным циклом.
4. **Отключение прерываний при инициализации** — `cli()` перед настройкой периферии исключает гонки при старте.
---
@@ -142,12 +142,12 @@
### Алгоритм сопряжения (pairing)
Конечный автомат `zh_do_pairing()` работает в четырёх состояниях:
Конечный автомат `_zh_do_pairing()` работает в четырёх состояниях:
1. **`ZH_NRF24_PAIR_SEND`** — генерируется псевдослучайный токен, формируется пакет запроса (`zh_nrf24_sensor_pairing_data_t` с `magic = ZH_NRF24_PAIRING_REQ_MAGIC`), выполняется неблокирующая передача через `zh_nrf24_send_no_wait()`.
1. **`ZH_NRF24_PAIR_SEND`** — генерируется псевдослучайный токен, формируется пакет запроса (`zh_nrf24_sensor_pairing_data_t` с `magic = ZH_NRF24_PAIRING_REQ_MAGIC`), выполняется неблокирующая передача через `_zh_nrf24_send_no_wait()`.
2. **`ZH_NRF24_PAIR_TX_WAIT`** — ожидание прерывания IRQ (завершение передачи). Если пин IRQ уже низкий — событие считается наступившим. Иначе — переход в сон с watchdog-таймером 250 мс. При флаге `TX_DS` — переход в приём, при `MAX_RT` — в backoff.
3. **`ZH_NRF24_PAIR_RX_WAIT`** — ожидание ответа шлюза. При получении пакета проверяется: длина равна `ZH_NRF24_PAIRING_PACKET_SIZE`, `magic == ZH_NRF24_PAIRING_ACK_MAGIC`, тип совпадает, токен совпадает, `id != 0` и `id != DEVICE_ID_UNASSIGNED`. При успехе — сохранение `id` в EEPROM и возврат.
4. **`ZH_NRF24_PAIR_BACKOFF`** — переход в Power Down, ожидание 4 с через watchdog. После `PAIRING_TIMEOUT_ATTEMPTS` (7) неудачных попыток — переход в `zh_enter_final_sleep()`.
4. **`ZH_NRF24_PAIR_BACKOFF`** — переход в Power Down, ожидание 4 с через watchdog. После `PAIRING_TIMEOUT_ATTEMPTS` (7) неудачных попыток — переход в `_zh_enter_final_sleep()`.
### Алгоритм измерения напряжения батареи
@@ -177,10 +177,10 @@
### Алгоритм сна и пробуждения
- Главный цикл проверяет флаг `send_request`.
- Главный цикл проверяет флаг `_send_request`.
- Если флаг не установлен — вызывается `sleep_cpu()` (режим Power-down).
- Пробуждение происходит по аппаратному прерыванию INT1 (rising edge на PD3).
- ISR устанавливает `send_request = true`, цикл просыпается и выполняет передачу.
- ISR устанавливает `_send_request = true`, цикл просыпается и выполняет передачу.
---
@@ -197,51 +197,51 @@
#include "stdbool.h"
#include "zh_nrf24_config.h"
static volatile uint8_t send_request = false;
zh_nrf24_sensor_transmitted_data_t transmitted_data = {0};
static volatile bool _send_request = false;
zh_nrf24_sensor_transmitted_data_t _transmitted_data = {0};
ISR(INT1_vect)
{
send_request = true;
_send_request = true;
}
int main(void)
{
transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH;
_transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH;
MCUSR &= ~(1 << WDRF);
wdt_disable();
cli();
zh_pad_interrupt_init();
zh_spi_init();
zh_nrf24_init();
_zh_pad_interrupt_init();
_zh_spi_init();
_zh_nrf24_init();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
// Загрузка или получение идентификатора устройства
uint8_t device_id = zh_load_device_id();
uint8_t device_id = _zh_load_device_id();
if (device_id == DEVICE_ID_UNASSIGNED)
{
device_id = zh_do_pairing();
device_id = _zh_do_pairing();
}
transmitted_data.id = (int16_t)device_id;
_transmitted_data.id = (int16_t)device_id;
for (;;)
{
if (send_request == true)
if (_send_request == true)
{
cli();
send_request = false;
_send_request = false;
sei();
transmitted_data.battery = (int16_t)lroundf(zh_get_battery_voltage() * 100.0);
_transmitted_data.battery = (int16_t)lroundf(_zh_get_battery_voltage() * 100.0);
uint8_t payload[ZH_NRF24_MAX_PAYLOAD_SIZE];
uint8_t size = zh_nrf24_sensor_build_payload(&transmitted_data, payload, sizeof(payload));
uint8_t size = zh_nrf24_sensor_build_payload(&_transmitted_data, payload, sizeof(payload));
if (size > 0)
{
zh_nrf24_send(payload, size);
_zh_nrf24_send(payload, size);
}
}
else
{
cli();
if (send_request == false)
if (_send_request == false)
{
sleep_enable();
sei();
@@ -284,11 +284,11 @@ int main(void)
| Условие | Поведение |
| --------- | ----------- |
| Нулевое показание АЦП | `zh_get_battery_voltage()` возвращает `0.0` |
| Нулевое показание АЦП | `_zh_get_battery_voltage()` возвращает `0.0` |
| Превышение таймаута передачи (100 мс) | Передача прерывается, пакет теряется |
| Неверная длина принятого пакета при сопряжении | Пакет отбрасывается, переход в `ZH_NRF24_PAIR_BACKOFF` |
| Превышение числа попыток сопряжения (7) | `zh_enter_final_sleep()` — сон до сброса |
| `zh_nrf24_sensor_build_payload()` возвращает 0 | Передача пропускается, переход в `zh_enter_final_sleep()` |
| Превышение числа попыток сопряжения (7) | `_zh_enter_final_sleep()` — сон до сброса |
| `zh_nrf24_sensor_build_payload()` возвращает 0 | Передача пропускается, переход в `_zh_enter_final_sleep()` |
---
@@ -298,9 +298,9 @@ int main(void)
2. **Отсутствие шифрования** — CRC включён, но AES-шифрование не используется. Пакеты могут быть перехвачены.
3. **Жёстко зашитый адрес и канал шлюза** — смена `GATEWAY_ADDRESS` или `GATEWAY_CHANNEL` требует перепрошивки.
4. **Таймаут блокирующей передачи 100 мс** — если шлюз недоступен, пакет теряется без повторной попытки на уровне приложения (аппаратные ретрансмиты настроены через `SETUP_RETR = 0xFF`: 15 попыток с максимальным интервалом).
5. **Одно сенсорное событие за цикл** — несколько касаний во время передачи будут потеряны (флаг `send_request` — один бит).
5. **Одно сенсорное событие за цикл** — несколько касаний во время передачи будут потеряны (флаг `_send_request` — один бит).
6. **Точность измерения батареи** — зависит от стабильности внутреннего опорного напряжения 1,1 В и может отличаться от реального напряжения на ±3%.
7. **SPI остаётся включённым в режиме сна** — перед окончательным сном SPI отключается в `zh_enter_final_sleep()`, но в штатном режиме ожидания SPI не отключается между передачами.
7. **SPI остаётся включённым в режиме сна** — перед окончательным сном SPI отключается в `_zh_enter_final_sleep()`, но в штатном режиме ожидания SPI не отключается между передачами.
---
@@ -326,7 +326,7 @@ pio run -e ATmega328P -t upload
### Подключение в проекте
Компонент является самодостаточной прошивкой — не подключается как библиотека. Для интеграции в другой проект скопируйте `src/main.c`, добавьте зависимость `zh_nrf24_config` и адаптируйте макросы конфигурации.
Компонент является самодостаточной прошивкой — не подключается как библиотека. Для интеграции в другой проект скопируйте `src/zh_avr_touch_pad.c`, добавьте зависимость `zh_nrf24_config` и адаптируйте макросы конфигурации.
```ini
; platformio.ini