bbdcc1e623
- main.c: file-header comment describing the hardware and operation, logic split into named phases (sleep_until_interrupt, wake_peripheral_rails, take_counts_snapshot, send_wheel_counts_report, handle_minute_alarm, init_all_hardware); shared state renamed to say what it is and made static. - rfm69.c: reorganized into six labeled sections; cond_1/2/3 and hash scratch globals replaced by a reply_acknowledges() helper with clear locals; packet layout and every init register write documented. - LOG() macro (compiled out when DO_UART is off) replaces the #if DO_UART blocks that obscured the logic. - Drivers: file-header comments; named RTC_REG_*/RTC_ALM_MASK_BIT constants; EEPROM spool scheme documented; ADC_CHANNEL_BANDGAP named; repeated pin if/else helpers collapsed to SET_PIN_TO(). - Removed unused globals/buffers and commented-out code; ran clang-format with the project style. Register writes and radio protocol are byte-identical. Builds clean under -Wall -Wextra on gnu17 and c23; flash 13028 -> 12830 B, static RAM 1038 -> 999 B. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YVJKatfeMJjAmuH9KYiLuv
115 lines
3.3 KiB
C
115 lines
3.3 KiB
C
// MAX31329 RTC driver, plus the over-the-radio time sync that seeds it.
|
|
|
|
#include "max31329.h"
|
|
|
|
RTC_RFM69_STATUS set_time_from_rfm69(identifier_results id_data)
|
|
{
|
|
rfm69_init();
|
|
_delay_ms(1);
|
|
|
|
reset_txrx_struct(&TX_DATA);
|
|
memcpy(TX_DATA.msg, id_data.name_str, MIN(10, id_data.name_len));
|
|
memcpy(TX_DATA.msg + 10, id_data.diameter_str, MIN(10, id_data.diameter_len));
|
|
TX_DATA.len = 20;
|
|
TX_DATA.flags = MSG_REQ_CTIME;
|
|
TX_DATA.dtype = MSG_TYPE_STRING;
|
|
|
|
rfm69_write_msg(TX_DATA);
|
|
|
|
if (wait_rx_payload_ready_timeout(100)) {
|
|
RX_DATA = rfm69_read_msg();
|
|
if (RX_DATA.flags == MSG_RESP_CTIME) {
|
|
|
|
// Seed the seconds from the name hash instead of the reply so
|
|
// nodes don't all wake and transmit in the same instant.
|
|
TIME.Second = id_data.hashed;
|
|
|
|
TIME.Minute = RX_DATA.msg[1];
|
|
TIME.Hour = RX_DATA.msg[2];
|
|
TIME.Day = RX_DATA.msg[3];
|
|
TIME.Month = RX_DATA.msg[4];
|
|
TIME.Year = RX_DATA.msg[5];
|
|
TIME.Wday = RX_DATA.msg[6];
|
|
|
|
rtc_write_time(TIME);
|
|
return RTC_RFM69_SET_TIME_SUCCESS;
|
|
}
|
|
}
|
|
return RTC_RFM69_SET_TIME_FAILED;
|
|
}
|
|
|
|
// Masking out minutes, hours, and day makes alarm 2 match once every minute
|
|
uint8_t rtc_set_per_minute_alarm(void)
|
|
{
|
|
DATA_BUFFER_7[0] = RTC_ALM_MASK_BIT;
|
|
DATA_BUFFER_7[1] = RTC_ALM_MASK_BIT;
|
|
DATA_BUFFER_7[2] = RTC_ALM_MASK_BIT;
|
|
|
|
return write_n_bytes(I2C_ADDR, RTC_REG_ALM2_MIN, DATA_BUFFER_7, 3);
|
|
}
|
|
|
|
void uart_print_rtc_time(time_struct td)
|
|
{
|
|
char str_rtc[26];
|
|
snprintf(
|
|
str_rtc, sizeof(str_rtc), "%u/%02u/%02u %u:%02u:%02u", 2000 + td.Year, td.Month, td.Day,
|
|
td.Hour, td.Minute, td.Second);
|
|
uart_sendString(str_rtc);
|
|
uart_sendString("\n");
|
|
}
|
|
|
|
uint8_t rtc_read_register(uint8_t addr) { return read_one_byte_no_err_register(I2C_ADDR, addr); }
|
|
|
|
uint8_t rtc_read_status_register(void) { return rtc_read_register(RTC_REG_STATUS); }
|
|
|
|
uint8_t rtc_read_interrupt_register(void) { return rtc_read_register(RTC_REG_INT_EN); }
|
|
|
|
uint8_t rtc_set_alarm_config(void) { return write_one_byte(I2C_ADDR, RTC_REG_CONFIG2, 0b00001010); }
|
|
|
|
uint8_t rtc_enable_interrupts(void)
|
|
{
|
|
return write_one_byte(I2C_ADDR, RTC_REG_INT_EN, RTC_INT_EN_A2IE);
|
|
}
|
|
|
|
uint8_t rtc_read_time_array(uint8_t* data)
|
|
{
|
|
return read_n_bytes(I2C_ADDR, RTC_REG_SECONDS, data, 7);
|
|
}
|
|
|
|
time_struct rtc_read_time(void)
|
|
{
|
|
|
|
rtc_read_time_array(DATA_BUFFER_7);
|
|
TIME.Second = BCD2DEC(DATA_BUFFER_7[0]);
|
|
TIME.Minute = BCD2DEC(DATA_BUFFER_7[1]);
|
|
TIME.Hour = BCD2DEC((DATA_BUFFER_7[2] & ~(1 << 6)));
|
|
TIME.Wday = DATA_BUFFER_7[3];
|
|
TIME.Day = BCD2DEC(DATA_BUFFER_7[4]);
|
|
TIME.Month = BCD2DEC((DATA_BUFFER_7[5] & ~(1 << 7)));
|
|
TIME.Year = tmYearToY2k(BCD2DEC(DATA_BUFFER_7[6]));
|
|
#if DO_UART
|
|
uart_print_rtc_time(TIME);
|
|
#endif
|
|
return TIME;
|
|
};
|
|
|
|
uint8_t rtc_write_time(time_struct tm)
|
|
{
|
|
|
|
if (i2c_start((I2C_ADDR << 1) | 0x00))
|
|
return 1;
|
|
|
|
uint8_t err = 0;
|
|
err |= i2c_write(RTC_REG_SECONDS);
|
|
err |= i2c_write(DEC2BCD(tm.Second));
|
|
err |= i2c_write(DEC2BCD(tm.Minute));
|
|
err |= i2c_write(DEC2BCD(tm.Hour));
|
|
err |= i2c_write(tm.Wday);
|
|
err |= i2c_write(DEC2BCD(tm.Day));
|
|
err |= i2c_write(DEC2BCD(tm.Month));
|
|
err |= i2c_write(DEC2BCD(y2kYearToTm(tm.Year)));
|
|
|
|
i2c_stop();
|
|
return err ? 1 : 0;
|
|
}
|