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

+147 -147
View File
@@ -95,23 +95,23 @@
* *
* @return Stored device id, or DEVICE_ID_UNASSIGNED if none is stored * @return Stored device id, or DEVICE_ID_UNASSIGNED if none is stored
*/ */
static uint8_t zh_load_device_id(void); static uint8_t _zh_load_device_id(void);
/** /**
* @brief Save the device identifier to EEPROM. * @brief Save the device identifier to EEPROM.
* *
* @param id Device identifier to store * @param id Device identifier to store
*/ */
static void zh_save_device_id(uint8_t id); static void _zh_save_device_id(uint8_t id);
/** /**
* @brief Initialize INT1 external interrupt for the touch-pad wake-up signal. * @brief Initialize INT1 external interrupt for the touch-pad wake-up signal.
* *
* Configures PD3 as a rising-edge triggered external interrupt source and * Configures PD3 as a rising-edge triggered external interrupt source and
* enables the INT1 interrupt mask bit. The ISR sets the send_request flag * enables the INT1 interrupt mask bit. The ISR sets the _send_request flag
* to trigger a radio transmission from the main loop. * to trigger a radio transmission from the main loop.
*/ */
static void zh_pad_interrupt_init(void); static void _zh_pad_interrupt_init(void);
/** /**
* @brief Initialize the hardware SPI peripheral in master mode. * @brief Initialize the hardware SPI peripheral in master mode.
@@ -119,7 +119,7 @@ static void zh_pad_interrupt_init(void);
* Configures MOSI, SCK and SS pins as outputs, drives SS high, and enables * Configures MOSI, SCK and SS pins as outputs, drives SS high, and enables
* SPI with Fosc/16 clock rate. * SPI with Fosc/16 clock rate.
*/ */
static void zh_spi_init(void); static void _zh_spi_init(void);
/** /**
* @brief Perform a single full-duplex SPI byte transfer. * @brief Perform a single full-duplex SPI byte transfer.
@@ -128,7 +128,7 @@ static void zh_spi_init(void);
* *
* @return Byte received from the slave during the transfer * @return Byte received from the slave during the transfer
*/ */
static uint8_t zh_spi_transfer(uint8_t data); static uint8_t _zh_spi_transfer(uint8_t data);
/** /**
* @brief Initialize the nRF24L01+ transceiver for TX-only operation. * @brief Initialize the nRF24L01+ transceiver for TX-only operation.
@@ -137,16 +137,16 @@ static uint8_t zh_spi_transfer(uint8_t data);
* settings, channel, RF power and data rate, and loads the gateway address * settings, channel, RF power and data rate, and loads the gateway address
* into both TX and RX pipe 0 registers. * into both TX and RX pipe 0 registers.
*/ */
static void zh_nrf24_init(void); static void _zh_nrf24_init(void);
/** /**
* @brief Initialize INT0 external interrupt for the nRF24 IRQ signal. * @brief Initialize INT0 external interrupt for the nRF24 IRQ signal.
* *
* Configures PD2 as a falling-edge triggered external interrupt source and * Configures PD2 as a falling-edge triggered external interrupt source and
* enables the INT0 interrupt mask bit. The ISR sets the nrf_event flag used * enables the INT0 interrupt mask bit. The ISR sets the _nrf_event flag used
* by the pairing state machine. * by the pairing state machine.
*/ */
static void zh_nrf24_interrupt_init(void); static void _zh_nrf24_interrupt_init(void);
/** /**
* @brief Transmit a payload buffer through the nRF24L01+ module. * @brief Transmit a payload buffer through the nRF24L01+ module.
@@ -158,7 +158,7 @@ static void zh_nrf24_interrupt_init(void);
* @param buf Pointer to the payload data to transmit (must not be NULL) * @param buf Pointer to the payload data to transmit (must not be NULL)
* @param size Number of bytes in the payload buffer (must be > 0) * @param size Number of bytes in the payload buffer (must be > 0)
*/ */
static void zh_nrf24_send(uint8_t *buf, uint8_t size); static void _zh_nrf24_send(uint8_t *buf, uint8_t size);
/** /**
* @brief Start a transmission without blocking on completion. * @brief Start a transmission without blocking on completion.
@@ -169,7 +169,7 @@ static void zh_nrf24_send(uint8_t *buf, uint8_t size);
* @param buf Pointer to the payload data to transmit (must not be NULL) * @param buf Pointer to the payload data to transmit (must not be NULL)
* @param size Number of bytes in the payload buffer (must be > 0) * @param size Number of bytes in the payload buffer (must be > 0)
*/ */
static void zh_nrf24_send_no_wait(uint8_t *buf, uint8_t size); static void _zh_nrf24_send_no_wait(uint8_t *buf, uint8_t size);
/** /**
* @brief Send a single-byte command to the nRF24L01+ and read the status. * @brief Send a single-byte command to the nRF24L01+ and read the status.
@@ -178,7 +178,7 @@ static void zh_nrf24_send_no_wait(uint8_t *buf, uint8_t size);
* *
* @return Status register value returned by the nRF24L01+ * @return Status register value returned by the nRF24L01+
*/ */
static uint8_t zh_nrf24_send_command(uint8_t cmd); static uint8_t _zh_nrf24_send_command(uint8_t cmd);
/** /**
* @brief Write a data buffer to the nRF24L01+ via SPI with a given command. * @brief Write a data buffer to the nRF24L01+ via SPI with a given command.
@@ -192,7 +192,7 @@ static uint8_t zh_nrf24_send_command(uint8_t cmd);
* *
* @return Status register value returned by the nRF24L01+ * @return Status register value returned by the nRF24L01+
*/ */
static uint8_t zh_nrf24_write_buffer(uint8_t cmd, uint8_t *buf, uint8_t count); static uint8_t _zh_nrf24_write_buffer(uint8_t cmd, uint8_t *buf, uint8_t count);
/** /**
* @brief Write a single byte value to an nRF24L01+ register. * @brief Write a single byte value to an nRF24L01+ register.
@@ -202,12 +202,12 @@ static uint8_t zh_nrf24_write_buffer(uint8_t cmd, uint8_t *buf, uint8_t count);
* *
* @return Status register value returned by the nRF24L01+ * @return Status register value returned by the nRF24L01+
*/ */
static uint8_t zh_nrf24_write_register(uint8_t reg, uint8_t val); static uint8_t _zh_nrf24_write_register(uint8_t reg, uint8_t val);
/** /**
* @brief Write a multi-byte buffer into an nRF24L01+ register. * @brief Write a multi-byte buffer into an nRF24L01+ register.
* *
* Convenience wrapper around zh_nrf24_write_buffer that prepends the * Convenience wrapper around _zh_nrf24_write_buffer that prepends the
* W_REGISTER command to the register address. * W_REGISTER command to the register address.
* *
* @param reg Register address to write to * @param reg Register address to write to
@@ -216,7 +216,7 @@ static uint8_t zh_nrf24_write_register(uint8_t reg, uint8_t val);
* *
* @return Status register value returned by the nRF24L01+ * @return Status register value returned by the nRF24L01+
*/ */
static uint8_t zh_nrf24_write_buff_register(uint8_t reg, uint8_t *buf, uint8_t count); static uint8_t _zh_nrf24_write_buff_register(uint8_t reg, uint8_t *buf, uint8_t count);
/** /**
* @brief Read the received payload from the nRF24L01+ into a buffer. * @brief Read the received payload from the nRF24L01+ into a buffer.
@@ -224,43 +224,43 @@ static uint8_t zh_nrf24_write_buff_register(uint8_t reg, uint8_t *buf, uint8_t c
* @param buf Pointer to the destination buffer (must not be NULL) * @param buf Pointer to the destination buffer (must not be NULL)
* @param count Number of bytes to read from the RX FIFO * @param count Number of bytes to read from the RX FIFO
*/ */
static void zh_nrf24_read_payload(uint8_t *buf, uint8_t count); static void _zh_nrf24_read_payload(uint8_t *buf, uint8_t count);
/** /**
* @brief Read the width of the payload in the nRF24L01+ RX FIFO. * @brief Read the width of the payload in the nRF24L01+ RX FIFO.
* *
* @return Payload width in bytes * @return Payload width in bytes
*/ */
static uint8_t zh_nrf24_read_payload_width(void); static uint8_t _zh_nrf24_read_payload_width(void);
/** /**
* @brief Switch the nRF24L01+ to RX mode on pipe 0. * @brief Switch the nRF24L01+ to RX mode on pipe 0.
*/ */
static void zh_nrf24_enter_rx(void); static void _zh_nrf24_enter_rx(void);
/** /**
* @brief Put the nRF24L01+ into power-down mode. * @brief Put the nRF24L01+ into power-down mode.
*/ */
static void zh_nrf24_enter_power_down(void); static void _zh_nrf24_enter_power_down(void);
/** /**
* @brief Start the watchdog timer in interrupt mode with the given timeout. * @brief Start the watchdog timer in interrupt mode with the given timeout.
* *
* @param timeout_bits Watchdog timeout prescaler bits (WDP3:0) * @param timeout_bits Watchdog timeout prescaler bits (WDP3:0)
*/ */
static void zh_wdt_start(uint8_t timeout_bits); static void _zh_wdt_start(uint8_t timeout_bits);
/** /**
* @brief Stop the watchdog timer. * @brief Stop the watchdog timer.
*/ */
static void zh_wdt_stop(void); static void _zh_wdt_stop(void);
/** /**
* @brief Generate a pseudo-random token from MCU state and ADC noise. * @brief Generate a pseudo-random token from MCU state and ADC noise.
* *
* @return 16-bit random token (never zero) * @return 16-bit random token (never zero)
*/ */
static uint16_t zh_get_random_token(void); static uint16_t _zh_get_random_token(void);
/** /**
* @brief Run the non-blocking pairing procedure to obtain a device id. * @brief Run the non-blocking pairing procedure to obtain a device id.
@@ -271,7 +271,7 @@ static uint16_t zh_get_random_token(void);
* *
* @return Device identifier assigned by the gateway * @return Device identifier assigned by the gateway
*/ */
static uint8_t zh_do_pairing(void); static uint8_t _zh_do_pairing(void);
/** /**
* @brief Enter permanent power-down sleep until the next reset. * @brief Enter permanent power-down sleep until the next reset.
@@ -279,7 +279,7 @@ static uint8_t zh_do_pairing(void);
* Disables all interrupts, the watchdog, the radio, the ADC, SPI and all * Disables all interrupts, the watchdog, the radio, the ADC, SPI and all
* unused peripheral clocks, then loops in power-down sleep mode. * unused peripheral clocks, then loops in power-down sleep mode.
*/ */
static void zh_enter_final_sleep(void); static void _zh_enter_final_sleep(void);
/** /**
* @brief Measure the battery voltage using the internal AVcc reference. * @brief Measure the battery voltage using the internal AVcc reference.
@@ -290,56 +290,56 @@ static void zh_enter_final_sleep(void);
* *
* @return Battery voltage in volts, or 0.0 if the ADC reading is zero * @return Battery voltage in volts, or 0.0 if the ADC reading is zero
*/ */
static float zh_get_battery_voltage(void); static float _zh_get_battery_voltage(void);
static volatile uint8_t send_request = false; static volatile bool _send_request = false;
static volatile uint8_t nrf_event = false; static volatile bool _nrf_event = false;
zh_nrf24_sensor_transmitted_data_t transmitted_data = {0}; zh_nrf24_sensor_transmitted_data_t _transmitted_data = {0};
int main(void) int main(void)
{ {
transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH; _transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH;
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
cli(); cli();
zh_pad_interrupt_init(); _zh_pad_interrupt_init();
zh_spi_init(); _zh_spi_init();
zh_nrf24_init(); _zh_nrf24_init();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei(); sei();
uint8_t device_id = zh_load_device_id(); uint8_t device_id = _zh_load_device_id();
if (device_id == DEVICE_ID_UNASSIGNED) 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;
{ {
uint8_t probe[ZH_NRF24_MAX_PAYLOAD_SIZE]; uint8_t probe[ZH_NRF24_MAX_PAYLOAD_SIZE];
if (zh_nrf24_sensor_build_payload(&transmitted_data, probe, sizeof(probe)) == 0) if (zh_nrf24_sensor_build_payload(&_transmitted_data, probe, sizeof(probe)) == 0)
{ {
zh_enter_final_sleep(); _zh_enter_final_sleep();
} }
} }
for (;;) for (;;)
{ {
if (send_request == true) if (_send_request == true)
{ {
cli(); cli();
send_request = false; _send_request = false;
sei(); 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 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) if (size > 0)
{ {
zh_nrf24_send(payload, size); _zh_nrf24_send(payload, size);
} }
} }
else else
{ {
cli(); cli();
if (send_request == false) if (_send_request == false)
{ {
sleep_enable(); sleep_enable();
sei(); sei();
@@ -354,19 +354,19 @@ int main(void)
ISR(INT1_vect) ISR(INT1_vect)
{ {
send_request = true; _send_request = true;
} }
ISR(INT0_vect) ISR(INT0_vect)
{ {
nrf_event = true; _nrf_event = true;
} }
ISR(WDT_vect) ISR(WDT_vect)
{ {
} }
static uint8_t zh_load_device_id(void) static uint8_t _zh_load_device_id(void)
{ {
uint8_t id = eeprom_read_byte(EEPROM_DEVICE_ID_ADDR); uint8_t id = eeprom_read_byte(EEPROM_DEVICE_ID_ADDR);
if (id == 0xFF || id == 0x00) if (id == 0xFF || id == 0x00)
@@ -376,12 +376,12 @@ static uint8_t zh_load_device_id(void)
return id; return id;
} }
static void zh_save_device_id(uint8_t id) static void _zh_save_device_id(uint8_t id)
{ {
eeprom_update_byte(EEPROM_DEVICE_ID_ADDR, id); eeprom_update_byte(EEPROM_DEVICE_ID_ADDR, id);
} }
static void zh_pad_interrupt_init(void) static void _zh_pad_interrupt_init(void)
{ {
DDRD &= ~(1 << PD3); DDRD &= ~(1 << PD3);
PORTD &= ~(1 << PD3); PORTD &= ~(1 << PD3);
@@ -391,14 +391,14 @@ static void zh_pad_interrupt_init(void)
EIMSK |= (1 << INT1); EIMSK |= (1 << INT1);
} }
static void zh_spi_init(void) static void _zh_spi_init(void)
{ {
DDRB |= (1 << PB2) | (1 << PB3) | (1 << PB5); DDRB |= (1 << PB2) | (1 << PB3) | (1 << PB5);
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
} }
static uint8_t zh_spi_transfer(uint8_t data) static uint8_t _zh_spi_transfer(uint8_t data)
{ {
SPDR = data; SPDR = data;
while ((SPSR & (1 << SPIF)) == 0) while ((SPSR & (1 << SPIF)) == 0)
@@ -407,7 +407,7 @@ static uint8_t zh_spi_transfer(uint8_t data)
return SPDR; return SPDR;
} }
static void zh_nrf24_init(void) static void _zh_nrf24_init(void)
{ {
_delay_ms(100); _delay_ms(100);
DDRB |= (1 << PB1); DDRB |= (1 << PB1);
@@ -416,23 +416,23 @@ static void zh_nrf24_init(void)
PORTD |= (1 << PD2); PORTD |= (1 << PD2);
uint64_t gateway_address = GATEWAY_ADDRESS; uint64_t gateway_address = GATEWAY_ADDRESS;
uint8_t activation_key = 0x73; uint8_t activation_key = 0x73;
zh_nrf24_write_register(NRF_REG_CONFIG, 0x00); _zh_nrf24_write_register(NRF_REG_CONFIG, 0x00);
zh_nrf24_write_register(NRF_REG_EN_AA, 0x01); _zh_nrf24_write_register(NRF_REG_EN_AA, 0x01);
zh_nrf24_write_register(NRF_REG_EN_RXADDR, 0x01); _zh_nrf24_write_register(NRF_REG_EN_RXADDR, 0x01);
zh_nrf24_write_register(NRF_REG_SETUP_AW, 0x01); _zh_nrf24_write_register(NRF_REG_SETUP_AW, 0x01);
zh_nrf24_write_register(NRF_REG_SETUP_RETR, 0xFF); _zh_nrf24_write_register(NRF_REG_SETUP_RETR, 0xFF);
zh_nrf24_write_register(NRF_REG_RF_CH, GATEWAY_CHANNEL); _zh_nrf24_write_register(NRF_REG_RF_CH, GATEWAY_CHANNEL);
zh_nrf24_write_register(NRF_REG_RF_SETUP, 0x26); _zh_nrf24_write_register(NRF_REG_RF_SETUP, 0x26);
zh_nrf24_write_buff_register(NRF_REG_TX_ADDR, (uint8_t *)&gateway_address, 3); _zh_nrf24_write_buff_register(NRF_REG_TX_ADDR, (uint8_t *)&gateway_address, 3);
zh_nrf24_write_buff_register(NRF_REG_RX_ADDR_P0, (uint8_t *)&gateway_address, 3); _zh_nrf24_write_buff_register(NRF_REG_RX_ADDR_P0, (uint8_t *)&gateway_address, 3);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
zh_nrf24_write_buffer(NRF_CMD_ACTIVATE, &activation_key, sizeof(activation_key)); _zh_nrf24_write_buffer(NRF_CMD_ACTIVATE, &activation_key, sizeof(activation_key));
zh_nrf24_write_register(NRF_REG_FEATURE, NRF_FEATURE_EN_DPL); _zh_nrf24_write_register(NRF_REG_FEATURE, NRF_FEATURE_EN_DPL);
zh_nrf24_write_register(NRF_REG_DYNPD, NRF_DYNPD_DPL_P0); _zh_nrf24_write_register(NRF_REG_DYNPD, NRF_DYNPD_DPL_P0);
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC);
} }
static void zh_nrf24_interrupt_init(void) static void _zh_nrf24_interrupt_init(void)
{ {
DDRD &= ~(1 << PD2); DDRD &= ~(1 << PD2);
PORTD |= (1 << PD2); PORTD |= (1 << PD2);
@@ -442,12 +442,12 @@ static void zh_nrf24_interrupt_init(void)
EIMSK |= (1 << INT0); EIMSK |= (1 << INT0);
} }
static void zh_nrf24_send(uint8_t *buf, uint8_t size) static void _zh_nrf24_send(uint8_t *buf, uint8_t size)
{ {
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP);
_delay_ms(5); _delay_ms(5);
zh_nrf24_send_command(NRF_CMD_FLUSH_TX); _zh_nrf24_send_command(NRF_CMD_FLUSH_TX);
zh_nrf24_write_buffer(NRF_CMD_W_TX_PAYLOAD, buf, size); _zh_nrf24_write_buffer(NRF_CMD_W_TX_PAYLOAD, buf, size);
PORTB |= (1 << PB1); PORTB |= (1 << PB1);
uint8_t count = 0; uint8_t count = 0;
while ((PIND & (1 << PD2)) != 0) while ((PIND & (1 << PD2)) != 0)
@@ -459,97 +459,97 @@ static void zh_nrf24_send(uint8_t *buf, uint8_t size)
_delay_ms(1); _delay_ms(1);
} }
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
uint8_t status = zh_nrf24_send_command(NRF_CMD_NOP); uint8_t status = _zh_nrf24_send_command(NRF_CMD_NOP);
zh_nrf24_write_register(NRF_REG_STATUS, status); _zh_nrf24_write_register(NRF_REG_STATUS, status);
zh_nrf24_send_command(NRF_CMD_FLUSH_TX); _zh_nrf24_send_command(NRF_CMD_FLUSH_TX);
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC);
} }
static void zh_nrf24_send_no_wait(uint8_t *buf, uint8_t size) static void _zh_nrf24_send_no_wait(uint8_t *buf, uint8_t size)
{ {
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_MASK_RX_DR | NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP);
_delay_ms(2); _delay_ms(2);
zh_nrf24_send_command(NRF_CMD_FLUSH_TX); _zh_nrf24_send_command(NRF_CMD_FLUSH_TX);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR);
zh_nrf24_write_buffer(NRF_CMD_W_TX_PAYLOAD, buf, size); _zh_nrf24_write_buffer(NRF_CMD_W_TX_PAYLOAD, buf, size);
PORTB |= (1 << PB1); PORTB |= (1 << PB1);
_delay_us(15); _delay_us(15);
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
} }
static uint8_t zh_nrf24_send_command(uint8_t cmd) static uint8_t _zh_nrf24_send_command(uint8_t cmd)
{ {
PORTB &= ~(1 << PB2); PORTB &= ~(1 << PB2);
uint8_t status = zh_spi_transfer(cmd); uint8_t status = _zh_spi_transfer(cmd);
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
return status; return status;
} }
static uint8_t zh_nrf24_write_buffer(uint8_t cmd, uint8_t *buf, uint8_t count) static uint8_t _zh_nrf24_write_buffer(uint8_t cmd, uint8_t *buf, uint8_t count)
{ {
PORTB &= ~(1 << PB2); PORTB &= ~(1 << PB2);
uint8_t status = zh_spi_transfer(cmd); uint8_t status = _zh_spi_transfer(cmd);
while (count-- != 0) while (count-- != 0)
{ {
zh_spi_transfer(*(buf++)); _zh_spi_transfer(*(buf++));
} }
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
return status; return status;
} }
static uint8_t zh_nrf24_write_register(uint8_t reg, uint8_t val) static uint8_t _zh_nrf24_write_register(uint8_t reg, uint8_t val)
{ {
PORTB &= ~(1 << PB2); PORTB &= ~(1 << PB2);
uint8_t status = zh_spi_transfer(reg | NRF_CMD_W_REGISTER); uint8_t status = _zh_spi_transfer(reg | NRF_CMD_W_REGISTER);
zh_spi_transfer(val); _zh_spi_transfer(val);
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
return status; return status;
} }
static uint8_t zh_nrf24_write_buff_register(uint8_t reg, uint8_t *buf, uint8_t count) static uint8_t _zh_nrf24_write_buff_register(uint8_t reg, uint8_t *buf, uint8_t count)
{ {
return zh_nrf24_write_buffer((reg | NRF_CMD_W_REGISTER), buf, count); return _zh_nrf24_write_buffer((reg | NRF_CMD_W_REGISTER), buf, count);
} }
static void zh_nrf24_read_payload(uint8_t *buf, uint8_t count) static void _zh_nrf24_read_payload(uint8_t *buf, uint8_t count)
{ {
PORTB &= ~(1 << PB2); PORTB &= ~(1 << PB2);
zh_spi_transfer(NRF_CMD_R_RX_PAYLOAD); _zh_spi_transfer(NRF_CMD_R_RX_PAYLOAD);
while (count-- != 0) while (count-- != 0)
{ {
*buf++ = zh_spi_transfer(0xFF); *buf++ = _zh_spi_transfer(0xFF);
} }
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
} }
static uint8_t zh_nrf24_read_payload_width(void) static uint8_t _zh_nrf24_read_payload_width(void)
{ {
PORTB &= ~(1 << PB2); PORTB &= ~(1 << PB2);
zh_spi_transfer(NRF_CMD_R_RX_PL_WID); _zh_spi_transfer(NRF_CMD_R_RX_PL_WID);
uint8_t width = zh_spi_transfer(0xFF); uint8_t width = _zh_spi_transfer(0xFF);
PORTB |= (1 << PB2); PORTB |= (1 << PB2);
return width; return width;
} }
static void zh_nrf24_enter_rx(void) static void _zh_nrf24_enter_rx(void)
{ {
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR);
zh_nrf24_send_command(NRF_CMD_FLUSH_RX); _zh_nrf24_send_command(NRF_CMD_FLUSH_RX);
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP | NRF_CONFIG_PRIM_RX); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_EN_CRC | NRF_CONFIG_PWR_UP | NRF_CONFIG_PRIM_RX);
_delay_ms(2); _delay_ms(2);
PORTB |= (1 << PB1); PORTB |= (1 << PB1);
_delay_us(130); _delay_us(130);
} }
static void zh_nrf24_enter_power_down(void) static void _zh_nrf24_enter_power_down(void)
{ {
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_EN_CRC); _zh_nrf24_write_register(NRF_REG_CONFIG, NRF_CONFIG_EN_CRC);
} }
static void zh_wdt_start(uint8_t timeout_bits) static void _zh_wdt_start(uint8_t timeout_bits)
{ {
uint8_t wdp = (timeout_bits & 0x07) | ((timeout_bits & 0x08) ? (1 << WDP3) : 0); uint8_t wdp = (timeout_bits & 0x07) | ((timeout_bits & 0x08) ? (1 << WDP3) : 0);
cli(); cli();
@@ -559,7 +559,7 @@ static void zh_wdt_start(uint8_t timeout_bits)
sei(); sei();
} }
static void zh_wdt_stop(void) static void _zh_wdt_stop(void)
{ {
cli(); cli();
wdt_reset(); wdt_reset();
@@ -568,7 +568,7 @@ static void zh_wdt_stop(void)
sei(); sei();
} }
static uint16_t zh_get_random_token(void) static uint16_t _zh_get_random_token(void)
{ {
uint16_t token = MCUSR; uint16_t token = MCUSR;
MCUSR = 0; MCUSR = 0;
@@ -591,16 +591,16 @@ static uint16_t zh_get_random_token(void)
return token; return token;
} }
static uint8_t zh_do_pairing(void) static uint8_t _zh_do_pairing(void)
{ {
uint16_t token = zh_get_random_token(); uint16_t token = _zh_get_random_token();
zh_nrf24_sensor_pairing_data_t pairing_request; zh_nrf24_sensor_pairing_data_t pairing_request;
pairing_request.type = (uint8_t)transmitted_data.type; pairing_request.type = (uint8_t)_transmitted_data.type;
pairing_request.magic = ZH_NRF24_PAIRING_REQ_MAGIC; pairing_request.magic = ZH_NRF24_PAIRING_REQ_MAGIC;
pairing_request.token_hi = (uint8_t)(token >> 8); pairing_request.token_hi = (uint8_t)(token >> 8);
pairing_request.token_lo = (uint8_t)(token & 0xFF); pairing_request.token_lo = (uint8_t)(token & 0xFF);
pairing_request.id = 0; pairing_request.id = 0;
zh_nrf24_interrupt_init(); _zh_nrf24_interrupt_init();
zh_nrf24_sensor_pairing_state_t state = ZH_NRF24_PAIR_SEND; zh_nrf24_sensor_pairing_state_t state = ZH_NRF24_PAIR_SEND;
uint8_t attempts = 0; uint8_t attempts = 0;
for (;;) for (;;)
@@ -608,34 +608,34 @@ static uint8_t zh_do_pairing(void)
switch (state) switch (state)
{ {
case ZH_NRF24_PAIR_SEND: case ZH_NRF24_PAIR_SEND:
nrf_event = false; _nrf_event = false;
zh_nrf24_send_no_wait((uint8_t *)&pairing_request, ZH_NRF24_PAIRING_PACKET_SIZE); _zh_nrf24_send_no_wait((uint8_t *)&pairing_request, ZH_NRF24_PAIRING_PACKET_SIZE);
state = ZH_NRF24_PAIR_TX_WAIT; state = ZH_NRF24_PAIR_TX_WAIT;
break; break;
case ZH_NRF24_PAIR_TX_WAIT: case ZH_NRF24_PAIR_TX_WAIT:
if ((PIND & (1 << PD2)) == 0) if ((PIND & (1 << PD2)) == 0)
{ {
nrf_event = true; _nrf_event = true;
} }
else else
{ {
nrf_event = false; _nrf_event = false;
zh_wdt_start(WDT_T_250MS); _zh_wdt_start(WDT_T_250MS);
sleep_enable(); sleep_enable();
sei(); sei();
sleep_cpu(); sleep_cpu();
sleep_disable(); sleep_disable();
zh_wdt_stop(); _zh_wdt_stop();
sei(); sei();
} }
if (nrf_event == true) if (_nrf_event == true)
{ {
nrf_event = false; _nrf_event = false;
uint8_t status = zh_nrf24_send_command(NRF_CMD_NOP); uint8_t status = _zh_nrf24_send_command(NRF_CMD_NOP);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT | NRF_STATUS_RX_DR);
if ((status & NRF_STATUS_TX_DS) != 0) if ((status & NRF_STATUS_TX_DS) != 0)
{ {
zh_nrf24_enter_rx(); _zh_nrf24_enter_rx();
state = ZH_NRF24_PAIR_RX_WAIT; state = ZH_NRF24_PAIR_RX_WAIT;
} }
else else
@@ -651,53 +651,53 @@ static uint8_t zh_do_pairing(void)
case ZH_NRF24_PAIR_RX_WAIT: case ZH_NRF24_PAIR_RX_WAIT:
if ((PIND & (1 << PD2)) == 0) if ((PIND & (1 << PD2)) == 0)
{ {
nrf_event = true; _nrf_event = true;
} }
else else
{ {
nrf_event = false; _nrf_event = false;
zh_wdt_start(WDT_T_250MS); _zh_wdt_start(WDT_T_250MS);
sleep_enable(); sleep_enable();
sei(); sei();
sleep_cpu(); sleep_cpu();
sleep_disable(); sleep_disable();
zh_wdt_stop(); _zh_wdt_stop();
sei(); sei();
} }
if (nrf_event == true) if (_nrf_event == true)
{ {
nrf_event = false; _nrf_event = false;
uint8_t status = zh_nrf24_send_command(NRF_CMD_NOP); uint8_t status = _zh_nrf24_send_command(NRF_CMD_NOP);
if ((status & NRF_STATUS_RX_DR) != 0) if ((status & NRF_STATUS_RX_DR) != 0)
{ {
uint8_t width = zh_nrf24_read_payload_width(); uint8_t width = _zh_nrf24_read_payload_width();
if (width > ZH_NRF24_MAX_PAYLOAD_SIZE) if (width > ZH_NRF24_MAX_PAYLOAD_SIZE)
{ {
zh_nrf24_send_command(NRF_CMD_FLUSH_RX); _zh_nrf24_send_command(NRF_CMD_FLUSH_RX);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR);
state = ZH_NRF24_PAIR_BACKOFF; state = ZH_NRF24_PAIR_BACKOFF;
break; break;
} }
if (width != ZH_NRF24_PAIRING_PACKET_SIZE) if (width != ZH_NRF24_PAIRING_PACKET_SIZE)
{ {
uint8_t dummy[ZH_NRF24_MAX_PAYLOAD_SIZE]; uint8_t dummy[ZH_NRF24_MAX_PAYLOAD_SIZE];
zh_nrf24_read_payload(dummy, width); _zh_nrf24_read_payload(dummy, width);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR);
zh_nrf24_send_command(NRF_CMD_FLUSH_RX); _zh_nrf24_send_command(NRF_CMD_FLUSH_RX);
state = ZH_NRF24_PAIR_BACKOFF; state = ZH_NRF24_PAIR_BACKOFF;
break; break;
} }
zh_nrf24_sensor_pairing_data_t pairing_response; zh_nrf24_sensor_pairing_data_t pairing_response;
zh_nrf24_read_payload((uint8_t *)&pairing_response, width); _zh_nrf24_read_payload((uint8_t *)&pairing_response, width);
zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT); _zh_nrf24_write_register(NRF_REG_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
zh_nrf24_send_command(NRF_CMD_FLUSH_RX); _zh_nrf24_send_command(NRF_CMD_FLUSH_RX);
if (pairing_response.magic == ZH_NRF24_PAIRING_ACK_MAGIC && pairing_response.type == pairing_request.type && if (pairing_response.magic == ZH_NRF24_PAIRING_ACK_MAGIC && pairing_response.type == pairing_request.type &&
pairing_response.token_hi == pairing_request.token_hi && pairing_response.token_lo == pairing_request.token_lo && pairing_response.token_hi == pairing_request.token_hi && pairing_response.token_lo == pairing_request.token_lo &&
pairing_response.id != 0 && pairing_response.id != DEVICE_ID_UNASSIGNED) pairing_response.id != 0 && pairing_response.id != DEVICE_ID_UNASSIGNED)
{ {
zh_nrf24_enter_power_down(); _zh_nrf24_enter_power_down();
EIMSK &= ~(1 << INT0); EIMSK &= ~(1 << INT0);
zh_save_device_id(pairing_response.id); _zh_save_device_id(pairing_response.id);
return pairing_response.id; return pairing_response.id;
} }
} }
@@ -709,18 +709,18 @@ static uint8_t zh_do_pairing(void)
} }
break; break;
case ZH_NRF24_PAIR_BACKOFF: case ZH_NRF24_PAIR_BACKOFF:
zh_nrf24_enter_power_down(); _zh_nrf24_enter_power_down();
nrf_event = false; _nrf_event = false;
zh_wdt_start(WDT_T_4S); _zh_wdt_start(WDT_T_4S);
sleep_enable(); sleep_enable();
sei(); sei();
sleep_cpu(); sleep_cpu();
sleep_disable(); sleep_disable();
zh_wdt_stop(); _zh_wdt_stop();
sei(); sei();
if (++attempts >= PAIRING_TIMEOUT_ATTEMPTS) if (++attempts >= PAIRING_TIMEOUT_ATTEMPTS)
{ {
zh_enter_final_sleep(); _zh_enter_final_sleep();
} }
state = ZH_NRF24_PAIR_SEND; state = ZH_NRF24_PAIR_SEND;
break; break;
@@ -728,14 +728,14 @@ static uint8_t zh_do_pairing(void)
} }
} }
static void zh_enter_final_sleep(void) static void _zh_enter_final_sleep(void)
{ {
cli(); cli();
EIMSK = 0; EIMSK = 0;
EIFR = 0xFF; EIFR = 0xFF;
zh_wdt_stop(); _zh_wdt_stop();
PORTB &= ~(1 << PB1); PORTB &= ~(1 << PB1);
zh_nrf24_write_register(NRF_REG_CONFIG, 0x00); _zh_nrf24_write_register(NRF_REG_CONFIG, 0x00);
ADCSRA = 0; ADCSRA = 0;
SPCR = 0; SPCR = 0;
PRR = (1 << PRTWI) | (1 << PRTIM2) | (1 << PRTIM1) | (1 << PRTIM0) | (1 << PRSPI) | (1 << PRUSART0); PRR = (1 << PRTWI) | (1 << PRTIM2) | (1 << PRTIM1) | (1 << PRTIM0) | (1 << PRSPI) | (1 << PRUSART0);
@@ -747,7 +747,7 @@ static void zh_enter_final_sleep(void)
} }
} }
static float zh_get_battery_voltage(void) static float _zh_get_battery_voltage(void)
{ {
ADMUX = (1 << REFS0) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1); ADMUX = (1 << REFS0) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1);
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
+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` (касание) | Главный цикл — запуск передачи | | `_send_request` | ISR `INT1_vect` (касание) | Главный цикл — запуск передачи |
| `nrf_event` | ISR `INT0_vect` (IRQ nRF24) | Конечный автомат сопряжения | | `_nrf_event` | ISR `INT0_vect` (IRQ nRF24) | Конечный автомат сопряжения |
--- ---
## API (интерфейс) ## API (интерфейс)
Все функции являются `static` и доступны только внутри модуля `main.c`. Все функции являются `static` и доступны только внутри модуля `src/zh_avr_touch_pad.c`. Имена функций имеют префикс `_zh_`.
### Инициализация ### Инициализация
| Функция | Описание | | Функция | Описание |
| --------- | ---------- | | --------- | ---------- |
| `zh_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию | | `_zh_pad_interrupt_init()` | Настройка внешнего прерывания INT1 (PD3, rising edge) для пробуждения по касанию |
| `zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) | | `_zh_spi_init()` | Инициализация аппаратного SPI в режиме мастера (Fosc/16) |
| `zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи | | `_zh_nrf24_init()` | Инициализация трансивера nRF24L01+ в режим передачи |
| `zh_nrf24_interrupt_init()` | Настройка внешнего прерывания INT0 (PD2, falling edge) для сигнала IRQ nRF24 | | `_zh_nrf24_interrupt_init()` | Настройка внешнего прерывания INT0 (PD2, falling edge) для сигнала IRQ nRF24 |
### Работа с EEPROM ### Работа с EEPROM
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_load_device_id()` | Чтение идентификатора устройства из EEPROM, возврат `DEVICE_ID_UNASSIGNED` если не сохранён | | `_zh_load_device_id()` | Чтение идентификатора устройства из EEPROM, возврат `DEVICE_ID_UNASSIGNED` если не сохранён |
| `zh_save_device_id()` | Сохранение идентификатора устройства в EEPROM | | `_zh_save_device_id()` | Сохранение идентификатора устройства в EEPROM |
### Измерение ### Измерение
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_get_battery_voltage()` | Измерение напряжения батареи через внутренний АЦП с опорой 1,1 В, возврат значения в вольтах | | `_zh_get_battery_voltage()` | Измерение напряжения батареи через внутренний АЦП с опорой 1,1 В, возврат значения в вольтах |
| `zh_get_random_token()` | Генерация 16-битного псевдослучайного токена из шума АЦП и MCUSR для запроса сопряжения | | `_zh_get_random_token()` | Генерация 16-битного псевдослучайного токена из шума АЦП и MCUSR для запроса сопряжения |
### Передача данных ### Передача данных
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_nrf24_send()` | Блокирующая передача буфера через nRF24L01+ с ожиданием завершения по пину IRQ (таймаут 100 мс) | | `_zh_nrf24_send()` | Блокирующая передача буфера через nRF24L01+ с ожиданием завершения по пину IRQ (таймаут 100 мс) |
| `zh_nrf24_send_no_wait()` | Неблокирующая передача — загружает буфер, импульс CE 15 мкс, завершение по прерыванию IRQ | | `_zh_nrf24_send_no_wait()` | Неблокирующая передача — загружает буфер, импульс CE 15 мкс, завершение по прерыванию IRQ |
### Управление режимами nRF24L01+ ### Управление режимами nRF24L01+
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_nrf24_enter_rx()` | Переключение nRF24L01+ в режим приёма на трубе 0 | | `_zh_nrf24_enter_rx()` | Переключение nRF24L01+ в режим приёма на трубе 0 |
| `zh_nrf24_enter_power_down()` | Перевод nRF24L01+ в режим Power Down | | `_zh_nrf24_enter_power_down()` | Перевод nRF24L01+ в режим Power Down |
### Низкоуровневые SPI-операции ### Низкоуровневые SPI-операции
| Функция | Описание | | Функция | Описание |
| --------- | ---------- | | --------- | ---------- |
| `zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) | | `_zh_spi_transfer()` | Обмен одного байта по SPI (полный дуплекс) |
| `zh_nrf24_send_command()` | Отправка однобайтовой команды и чтение регистра статуса | | `_zh_nrf24_send_command()` | Отправка однобайтовой команды и чтение регистра статуса |
| `zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ | | `_zh_nrf24_write_register()` | Запись одного байта в регистр nRF24L01+ |
| `zh_nrf24_write_buff_register()` | Запись многобайтового буфера в регистр nRF24L01+ | | `_zh_nrf24_write_buff_register()` | Запись многобайтового буфера в регистр nRF24L01+ |
| `zh_nrf24_write_buffer()` | Запись буфера данных с указанной SPI-командой | | `_zh_nrf24_write_buffer()` | Запись буфера данных с указанной SPI-командой |
| `zh_nrf24_read_payload()` | Чтение принятого пакета из RX FIFO nRF24 в буфер | | `_zh_nrf24_read_payload()` | Чтение принятого пакета из RX FIFO nRF24 в буфер |
| `zh_nrf24_read_payload_width()` | Чтение длины пакета в RX FIFO nRF24 | | `_zh_nrf24_read_payload_width()` | Чтение длины пакета в RX FIFO nRF24 |
### Watchdog-таймер ### Watchdog-таймер
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_wdt_start()` | Запуск watchdog-таймера в режиме прерывания с указанным таймаутом | | `_zh_wdt_start()` | Запуск watchdog-таймера в режиме прерывания с указанным таймаутом |
| `zh_wdt_stop()` | Остановка watchdog-таймера | | `_zh_wdt_stop()` | Остановка watchdog-таймера |
### Сон и сопряжение ### Сон и сопряжение
| Функция | Описание | | Функция | Описание |
|---------|----------| |---------|----------|
| `zh_do_pairing()` | Запуск конечного автомата сопряжения со шлюзом для получения идентификатора | | `_zh_do_pairing()` | Запуск конечного автомата сопряжения со шлюзом для получения идентификатора |
| `zh_enter_final_sleep()` | Переход в окончательный Power-down сон до сброса: отключение всех прерываний, watchdog, радиомодуля, АЦП, SPI и неиспользуемых периферийных блоков | | `_zh_enter_final_sleep()` | Переход в окончательный Power-down сон до сброса: отключение всех прерываний, watchdog, радиомодуля, АЦП, SPI и неиспользуемых периферийных блоков |
--- ---
@@ -131,9 +131,9 @@
Прошивка работает на bare-metal AVR без RTOS. Синхронизация между прерываниями и главным циклом реализуется следующим образом: Прошивка работает на 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 является атомарной операцией. 2. **Атомарная запись из ISR** — обработка прерывания устанавливает флаг в `true`. Запись одного байта на AVR является атомарной операцией.
3. **Отключение прерываний при проверке и сбросе флага** — `cli()` перед проверкой и сбросом `send_request` в главном цикле исключает гонку между ISR и главным циклом. 3. **Отключение прерываний при проверке и сбросе флага** — `cli()` перед проверкой и сбросом `_send_request` в главном цикле исключает гонку между ISR и главным циклом.
4. **Отключение прерываний при инициализации** — `cli()` перед настройкой периферии исключает гонки при старте. 4. **Отключение прерываний при инициализации** — `cli()` перед настройкой периферии исключает гонки при старте.
--- ---
@@ -142,12 +142,12 @@
### Алгоритм сопряжения (pairing) ### Алгоритм сопряжения (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. 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 и возврат. 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). - Если флаг не установлен — вызывается `sleep_cpu()` (режим Power-down).
- Пробуждение происходит по аппаратному прерыванию INT1 (rising edge на PD3). - Пробуждение происходит по аппаратному прерыванию INT1 (rising edge на PD3).
- ISR устанавливает `send_request = true`, цикл просыпается и выполняет передачу. - ISR устанавливает `_send_request = true`, цикл просыпается и выполняет передачу.
--- ---
@@ -197,51 +197,51 @@
#include "stdbool.h" #include "stdbool.h"
#include "zh_nrf24_config.h" #include "zh_nrf24_config.h"
static volatile uint8_t send_request = false; static volatile bool _send_request = false;
zh_nrf24_sensor_transmitted_data_t transmitted_data = {0}; zh_nrf24_sensor_transmitted_data_t _transmitted_data = {0};
ISR(INT1_vect) ISR(INT1_vect)
{ {
send_request = true; _send_request = true;
} }
int main(void) int main(void)
{ {
transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH; _transmitted_data.type = ZH_NRF24_SENSOR_TOUCH_SWITCH;
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
cli(); cli();
zh_pad_interrupt_init(); _zh_pad_interrupt_init();
zh_spi_init(); _zh_spi_init();
zh_nrf24_init(); _zh_nrf24_init();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei(); sei();
// Загрузка или получение идентификатора устройства // Загрузка или получение идентификатора устройства
uint8_t device_id = zh_load_device_id(); uint8_t device_id = _zh_load_device_id();
if (device_id == DEVICE_ID_UNASSIGNED) 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 (;;) for (;;)
{ {
if (send_request == true) if (_send_request == true)
{ {
cli(); cli();
send_request = false; _send_request = false;
sei(); 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 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) if (size > 0)
{ {
zh_nrf24_send(payload, size); _zh_nrf24_send(payload, size);
} }
} }
else else
{ {
cli(); cli();
if (send_request == false) if (_send_request == false)
{ {
sleep_enable(); sleep_enable();
sei(); sei();
@@ -284,11 +284,11 @@ int main(void)
| Условие | Поведение | | Условие | Поведение |
| --------- | ----------- | | --------- | ----------- |
| Нулевое показание АЦП | `zh_get_battery_voltage()` возвращает `0.0` | | Нулевое показание АЦП | `_zh_get_battery_voltage()` возвращает `0.0` |
| Превышение таймаута передачи (100 мс) | Передача прерывается, пакет теряется | | Превышение таймаута передачи (100 мс) | Передача прерывается, пакет теряется |
| Неверная длина принятого пакета при сопряжении | Пакет отбрасывается, переход в `ZH_NRF24_PAIR_BACKOFF` | | Неверная длина принятого пакета при сопряжении | Пакет отбрасывается, переход в `ZH_NRF24_PAIR_BACKOFF` |
| Превышение числа попыток сопряжения (7) | `zh_enter_final_sleep()` — сон до сброса | | Превышение числа попыток сопряжения (7) | `_zh_enter_final_sleep()` — сон до сброса |
| `zh_nrf24_sensor_build_payload()` возвращает 0 | Передача пропускается, переход в `zh_enter_final_sleep()` | | `zh_nrf24_sensor_build_payload()` возвращает 0 | Передача пропускается, переход в `_zh_enter_final_sleep()` |
--- ---
@@ -298,9 +298,9 @@ int main(void)
2. **Отсутствие шифрования** — CRC включён, но AES-шифрование не используется. Пакеты могут быть перехвачены. 2. **Отсутствие шифрования** — CRC включён, но AES-шифрование не используется. Пакеты могут быть перехвачены.
3. **Жёстко зашитый адрес и канал шлюза** — смена `GATEWAY_ADDRESS` или `GATEWAY_CHANNEL` требует перепрошивки. 3. **Жёстко зашитый адрес и канал шлюза** — смена `GATEWAY_ADDRESS` или `GATEWAY_CHANNEL` требует перепрошивки.
4. **Таймаут блокирующей передачи 100 мс** — если шлюз недоступен, пакет теряется без повторной попытки на уровне приложения (аппаратные ретрансмиты настроены через `SETUP_RETR = 0xFF`: 15 попыток с максимальным интервалом). 4. **Таймаут блокирующей передачи 100 мс** — если шлюз недоступен, пакет теряется без повторной попытки на уровне приложения (аппаратные ретрансмиты настроены через `SETUP_RETR = 0xFF`: 15 попыток с максимальным интервалом).
5. **Одно сенсорное событие за цикл** — несколько касаний во время передачи будут потеряны (флаг `send_request` — один бит). 5. **Одно сенсорное событие за цикл** — несколько касаний во время передачи будут потеряны (флаг `_send_request` — один бит).
6. **Точность измерения батареи** — зависит от стабильности внутреннего опорного напряжения 1,1 В и может отличаться от реального напряжения на ±3%. 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 ```ini
; platformio.ini ; platformio.ini