Skip to content

Conversation

@XuGuohui
Copy link
Member

@XuGuohui XuGuohui commented Nov 20, 2025

Note: This PR makes the AM18x5 driver generally available for all Particle platforms, except for B-series due to flash size constraint.

Features

  • Allow user app to detect the presence of AM18x5
  • Allow user app to configure the RTC source, either using internal RTC or the AM18x5
  • Allow user app to set alarm using AM18x5
  • Allow user app to configure the AM18x5 settings, e.g. pins, osc source, xt calibration data etc
  • Allow user app to use the watchdog from Am18x5 (MCU's reset pin is connected with AM18x5)
  • Allow user app to power gate the MCU by Am18x5 (MCU's power is controlled by AM18x5's PSW pin)

Known issues

  • AM18x5's interrupt pin cannot connect to IO expander, i.e. the interrupt pin must connect to MCU's GPIO directly, otherwise, the alarm function won't work.
  • AM18x5 watchdog is not cancelled in bootloader

Example app

#include "application.h"

SYSTEM_MODE(MANUAL);

SerialLogHandler l(115200, LOG_LEVEL_ALL);

STARTUP (
    System.enableFeature(FEATURE_EXRTC_DETECTION);

    SystemExternalRtcConfiguration config;
    config.defaultRtc(true)
          .watchdogInputPin(PIN_INVALID)
          .interruptPin(A7)
          .i2cInterface(HAL_I2C_INTERFACE1)
          .rcFallbackOnXtalFailure(true)
          .rcOnBatteryPowered(true)
          .oscSource(Am18x5Oscillator::EXTERNAL_CRYSTAL)
          .xtalCalibrationValue(-45);
    System.setExternalRtcConfiguration(config);
);

void setup() {
    while (!Serial.isConnected()) {
    }
    delay(1s);

    Log.info("External RTC present: %s", System.isExternalRtcPresent() ? "yes" : "no");

    SystemExternalRtcConfiguration config = {};
    if (System.getExternalRtcConfiguration(config) == SYSTEM_ERROR_NONE) {
        Log.info("Current EXRTC config: default_rtc=%d, wdi_pin=%d, int_pin=%d, i2c_if=%d, rc_fallback=%d, rc_on_battery=%d, osc_src=%d, osc_cal_xt=%d",
                config.defaultRtc(),
                config.watchdogInputPin(),
                config.interruptPin(),
                config.i2cInterface(),
                config.rcFallbackOnXtalFailure(),
                config.rcOnBatteryPowered(),
                config.oscSource(),
                config.xtalCalibrationValue());
    } else {
        Log.info("Failed to get EXRTC config");
    }

    // SystemExternalRtcSleepConfiguration sleepConf = {};
    // sleepConf.duration(5s);
    // sleepConf.exti(Am18x5ExtiPolarity::FALLING);
    // System.powerGatedByExternalRtc(sleepConf);

    struct timeval now;
    hal_rtc_get_time(&now, nullptr);
    Log.info("Current RTC time: %lld", now.tv_sec);
    now.tv_sec += 5;
    static volatile bool alarmFired = false;
    auto ms = millis();
    Log.info("Alarm RTC time: %lld", now.tv_sec);
    int r = hal_rtc_set_alarm(&now, 0, [](void* ctx) -> void {
        volatile bool* alarmFired = (volatile bool*)ctx;
        *alarmFired = true;
    }, (void*)&alarmFired, nullptr);
    if (r != 0) {
        Log.error("Failed to set RTC alarm: %d!!!!!", r);
        return;
    }
    Log.info("Waiting for RTC alarm...");
    while (!alarmFired && (millis() - ms) <= 8000) {
        delay(1);
    }
    if (alarmFired) {
        Log.info("RTC alarm fired!");
    } else {
        Log.error("RTC alarm did not fire within expected time!");
    }

    WatchdogConfiguration wdgConf = {};
    wdgConf.timeout(10s);
    ExternalWatchdog.init(wdgConf);
    ExternalWatchdog.start();
}

void loop() {
    static bool flag = false;
    if (!flag) {
        Time.setTimeSource(HAL_RTC_SOURCE_INTERNAL);
        flag = true;
    } else {
        Time.setTimeSource(HAL_RTC_SOURCE_EXTERNAL);
        flag = false;
    }
    Log.info("Time source: %d, %lld", Time.getTimeSource(), Time.now());
    ExternalWatchdog.refresh();
    delay(1s);
}

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@XuGuohui XuGuohui marked this pull request as ready for review November 20, 2025 19:19
@XuGuohui XuGuohui added this to the 6.3.5 milestone Nov 20, 2025
@XuGuohui XuGuohui changed the title Feature/built in am18x5 Built-in am18x5 driver in DVOS Nov 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants